CrewAI vs LangGraph:多智能体编排该选谁?一篇讲清,小白也能懂!

1 引言

对于需要在快速原型开发与未来可扩展性之间取得平衡的开发者而言,在CrewAI和LangGraph之间做选择并非易事。

就我个人而言,我更倾向于CrewAI,因为它设置简单且具有对开发者友好的抽象层。它能让你在几分钟内构建出可用于生产环境的智能体流程,专注于业务逻辑而非复杂的编排架构。这种易用性和快速迭代节奏使CrewAI非常适合许多项目。

话虽如此,LangGraph凭借其基于图的显式领域特定语言(DSL)以及在主流科技公司中的广泛采用,已迅速成为大型、有状态生产项目的首选框架。它提供了对状态、依赖关系和内存的细粒度控制,这对于复杂或长期运行的工作流往往是必需的。

图片

CrewAI 和 LangGraph 都是智能体编排相关的开源框架,前者采用代码优先的编排方式,后者则提供可视化编排能力。

1.1 CrewAI

  • 核心架构

    基于角色驱动的设计理念,将智能体编排抽象为团队协作模式。其核心概念是角色(Role)、任务(Task)和团队(Crew)。

  • 主要功能

    具有基于角色的 Agent 架构、动态任务规划和授权、复杂的 Agent 间通信协议、等级森严的团队结构、自适应任务执行机制等功能。

  • 编排方式

    采用代码优先的编排方式,将智能体建模为具有特定角色和目标的团队成员,开发者可通过自然语言定义每个 Agent 的角色和专长,分配任务,然后将它们组织成 “Crew” 来执行流程。

  • 适用场景

    适用于协作式创意写作系统、业务战略制定和市场分析、跨学科的科研协助、应急响应规划和优化等场景,适合快速开发原型,能帮助开发者快速构建智能体系统。

1.2 LangGraph

  • 核心架构

    将 Agent 的工作流抽象为一个有向图,图中的 “节点” 代表一个计算单元,“边” 则代表流程的走向,底层设计融合了状态机和图计算模型。

  • 主要功能

    具备有状态的交互和工作流程、多 Agent 协调与通信、基于图形的 Agent 互动表示法、内置错误处理和重试机制、规划和反思功能等。

  • 编排方式

    提供可视化编排能力,通过状态图来管理复杂的工作流程,开发者可以精确定义每一步的状态转移和逻辑分支。

  • 适用场景

    适合需要复杂条件判断的动态流程、状态依赖性强的多步骤任务以及需要错误恢复和重试机制的系统,如智能客服系统等企业级应用场景。

2 智能体步骤的绝对控制:LangGraph vs. CrewAI

LangGraph有一个不可否认的优势是,它能对工作流中智能体执行的每一个步骤提供绝对控制。得益于其显式的基于图的架构,你可以精确地定义节点、边和状态转换。这种细粒度的编排让你能够全面监控、干预和调试整个执行流程。

相比之下,CrewAI通过智能体和任务实现的抽象简化了设置并加快了开发速度,但有时这会以牺牲对内部步骤执行的直接可见性和控制为代价。编排逻辑更多是隐含在Crew抽象内部的“黑箱”,这可能使细粒度的干预更具挑战性。

不过,随着CrewAI中Flows功能的引入——通过明确定义的工作流协调智能体和任务——你可以重新获得对执行过程类似级别的控制和透明度。Flows功能允许你显式地建模序列、条件和分支,在保留CrewAI易用性的同时减少了“黑箱”效应。

下面的Java验证器示例清楚地展示了这一点:LangGraph显式地暴露每个节点和边,而CrewAI Flows则在更对开发者友好的环境中支持类似的受控分步执行和监控。

3 示例:Java验证器

为了说明CrewAI和LangGraph在抽象和工作流风格上的差异,下面是两个框架中“验证器”智能体的极简实现。该验证器的目标是验证、纠正和优化小型Java代码片段。工作流设计为一个循环:首先检查代码是否存在语法错误。如果发现错误,它会尝试纠正代码,然后重新进入验证步骤。这个“验证-纠正”循环会持续到代码被认为语法正确为止。只有此时,工作流才会进入优化代码可读性和性能的最终步骤。

3.1 CrewAI:使用Flow的Java验证器

图片

CrewAI Flows允许你在类式结构中定义多智能体工作流,这种结构对开发者来说很熟悉。你先声明智能体,然后使用装饰器(@start@router@listen)绘制流程。这种结构使逻辑紧凑且易于阅读。在这个特定示例中,我们选择在Flow中直接编排单个智能体,而不是使用完整的Crew。这种方法让我们能更直接地控制每个智能体的步骤,非常适合这种简单的循环过程。需要注意的是,在更复杂的场景中,CrewAI的灵活性允许你编排整个智能体团队,利用它们的集体智能实现不同层次的抽象。

from typing import Any, Dict, Listfrom dotenv import load_dotenvfrom pydantic import BaseModel, Fieldfrom crewai.agent import Agentfrom crewai.flow.flow import Flow, listen, start, router# 加载环境变量(如API密钥等)load_dotenv()# 代码验证状态模型,存储代码内容和语法检查状态class CodeValidationState(BaseModel):    code: str = ""  # 待处理的Java代码    syntax_status: str = ""  # 语法检查状态("correct"或"incorrect")# Java代码验证流程类,继承自Flow并指定状态模型class JavaCodeValidationFlow(Flow[CodeValidationState]):    # 语法分析智能体:负责检查Java代码的语法是否正确    analyzer_agent = Agent(        role="Java代码语法分析器",        goal="接收Java代码,并仅根据语法返回'correct'(正确)或'incorrect'(错误)",        backstory="你是一个细致且精确的代码质量检查工具。"    )    # 代码纠正智能体:负责修复语法错误    corrector_agent = Agent(        role="Java代码纠正器",        goal="接收语法错误的Java代码,仅返回语法有效的纠正后代码。只返回Java代码,不包含解释和markdown格式",        backstory="你是一名Java编程专家,擅长修复代码错误。",        verbose=True  # 输出详细日志    )    # 代码优化智能体:负责优化正确代码的可读性和性能    optimizer_agent = Agent(        role="Java代码优化器",        goal="接收语法正确的Java代码,在不改变逻辑的前提下优化其可读性和性能。只返回可编译的Java代码,不包含解释和markdown格式",        backstory="你是一名专注于代码优化的高级开发人员。"    )    @start("try_again")  # 标记为流程起点,下一步指向"try_again"(循环回分析步骤)    def start_analysis(self):        """启动工作流,将代码发送给分析器进行语法检查。"""        print(f"开始代码分析...\n {self.state.code}")        # 调用分析智能体检查代码语法        result = self.analyzer_agent.kickoff(self.state.code)        # 获取分析结果("correct"或"incorrect")        syntax_status = result.raw        self.state.syntax_status = syntax_status        print(f"分析器结果:{syntax_status}")    @router(start_analysis)  # 路由节点,接收start_analysis的输出    def conditional_next_step(self):        """根据语法检查结果决定下一步:纠正或优化。"""        syntax_status = self.state.syntax_status        print(f"条件路由判断:{syntax_status}")        if syntax_status == "correct":            return "correct"  # 语法正确,进入优化步骤        else:            return "incorrect"  # 语法错误,进入纠正步骤    @router("incorrect")  # 接收"incorrect"信号,执行代码纠正    def correct_code_step(self):        """执行代码纠正操作。"""        # 调用纠正智能体修复代码        result = self.corrector_agent.kickoff(self.state.code)        print(f"纠正器:代码已纠正。\n {result.raw}")        # 更新状态中的代码为纠正后的值        self.state.code = result.raw        return "try_again"  # 纠正后返回分析步骤重新检查    @listen("correct")  # 监听"correct"信号,执行代码优化    def optimize_code_step(self):        """执行代码优化操作。"""        # 调用优化智能体优化代码        result = self.optimizer_agent.kickoff(self.state.code)        self.state.code = result.raw        print("优化器:优化完成。")        print("\n工作流结束。最终优化后的代码:")        print("---" * 20)        print(self.state.code)        print("---" * 20)# 工作流示例用法def run_code_validation_flow():    # 初始Java代码(存在语法错误:缺少分号)    initial_java_code = """    public class Test {        public static void main(String[] args) {            System.out.println("Hello, World!"        }    }    """    # 创建流程实例    flow = JavaCodeValidationFlow()    print("启动CrewAI Java代码验证流程...\n")    # 启动工作流并传入初始代码    flow.kickoff(inputs={"code": initial_java_code})    return flowif __name__ == "__main__":    flow = run_code_validation_flow()    # 生成流程图并保存    flow.plot('my_flow_plot')

核心思路:在CrewAI中,你首先定义智能体的角色和目标,然后使用Flow来编排它们执行一系列步骤。Flow本身就像一个带方法的常规类,装饰器负责处理路由逻辑。这种结构使逻辑紧凑,与开发者的类式思维一致。注意,这里我们使用的是CrewAI默认的LLM(目前是“gpt-4o-mini”)。

3.2 LangGraph:使用Graph的Java验证器

图片

LangGraph的方法更显式且基础。你定义一个包含节点和边的图,其中每个节点都是一个函数。工作流的状态在节点之间显式传递,条件边用于管理流程。

import osfrom langgraph.graph import StateGraph, ENDfrom dotenv import load_dotenvfrom typing import TypedDict  # 导入类型字典from langchain_openai import OpenAI# 确保OpenAI API密钥已设置在环境变量OPENAI_API_KEY中load_dotenv()# 定义状态 schema(存储工作流中的数据)class CodeState(TypedDict):    code: str  # 待处理的Java代码    is_correct: bool  # 标记代码是否语法正确# Java验证器图类,继承自StateGraphclass JavaVerifierGraph(StateGraph):    def __init__(self):        # 初始化LangChain的OpenAI包装器(从环境变量读取OPENAI_API_KEY)        self.llm = OpenAI(model="gpt-4o-mini", temperature=0)        # 创建状态图实例,指定状态类型为CodeState        workflow = StateGraph(CodeState)        # 添加节点:分析、优化、纠正        workflow.add_node("start_analysis_node", self.start_analysis_node)  # 分析节点        workflow.add_node("optimize_code_node", self.optimize_code_node)  # 优化节点        workflow.add_node("correct_code_node", self.correct_code_node)  # 纠正节点        # 定义入口点(工作流从分析节点开始)        workflow.set_entry_point("start_analysis_node")        # 从分析节点添加条件边(根据分析结果决定下一步)        workflow.add_conditional_edges(            "start_analysis_node",            self.conditional_next_node,  # 条件判断函数            {                "optimize_code_node": "optimize_code_node",  # 语法正确则进入优化节点                "correct_code_node": "correct_code_node"  # 语法错误则进入纠正节点            }        )        # 从纠正节点添加边,回到分析节点(形成循环)        workflow.add_edge("correct_code_node", "start_analysis_node")        # 编译图(生成可执行的工作流)        self.graph = workflow.compile()    def llm_check_code_syntax(self, code: str) -> bool:        """调用LLM检查Java代码语法是否正确"""        prompt = (            "检查以下Java代码是否语法正确。"            "只返回'correct'或'incorrect'。\n\n"            f"Java代码:\n{code}\n\n答案:"        )        result = self.llm(prompt)        return result.strip().lower() == "correct"    def llm_correct_code(self, code: str) -> str:        """调用LLM纠正Java代码的语法错误"""        prompt = (            "将以下Java代码纠正为语法有效的代码。"            "只提供纠正后的代码,不包含解释。\n\n"            f"Java代码:\n{code}\n\n纠正后的Java代码:"        )        return self.llm(prompt).strip()    def llm_optimize_code(self, code: str) -> str:        """调用LLM优化语法正确的Java代码"""        prompt = (            "优化以下语法正确的Java代码,"            "提升其可读性和性能。只返回Java代码,不包含解释和markdown格式。\n\n"            f"Java代码:\n{code}\n\n优化后的Java代码:"        )        return self.llm(prompt).strip()    def start_analysis_node(self, state: CodeState):        """分析节点:检查代码语法并更新状态中的is_correct"""        code = state["code"]        print("分析器:通过LLM检查语法...")        is_correct = self.llm_check_code_syntax(code)        print(f"分析器:代码{'正确' if is_correct else '错误'}")        # 更新状态中的is_correct字段        return {"is_correct": is_correct}    def optimize_code_node(self, state: CodeState):        """优化节点:优化代码并结束工作流"""        code = state["code"]        print("优化器:通过LLM优化代码...")        optimized_code = self.llm_optimize_code(code)        print("优化器:优化完成。结束工作流。")        # 更新代码并指定流程结束        return {"code": optimized_code, "__end__": END}    def correct_code_node(self, state: CodeState):        """纠正节点:修复代码语法错误,之后回到分析节点"""        code = state["code"]        print("纠正器:通过LLM纠正代码...")        corrected_code = self.llm_correct_code(code)        print("纠正器:纠正完成。返回分析器重新检查。")        # 更新状态中的代码为纠正后的值        return {"code": corrected_code}    def conditional_next_node(self, state: CodeState):        """条件判断函数:根据is_correct决定下一步节点"""        return "optimize_code_node" if state.get("is_correct") else "correct_code_node"    def run_workflow(self, code):        """运行工作流的入口方法"""        initial_state = {            "code": code,            "is_correct": True  # 初始值,实际会被分析节点覆盖        }        print("开始通过invoke()执行工作流...\n")        # 运行工作流并获取最终状态        final_state = self.graph.invoke(initial_state)        print("\n工作流完成!")        print("-" * 50)        print("最终Java代码(已纠正并优化):\n")        print(final_state["code"])        print("-" * 50)        print(f"最终'is_correct'状态:{final_state['is_correct']}")    def get_graph(self):        """获取图对象(用于生成流程图)"""        return self.graph.get_graph()def run_code_validation_flow():    # 初始Java代码(存在语法错误:缺少分号)    initial_code = """    public class Test {        public static void main(String[] args) {            System.out.println("Hello World!")        }    }    """    # 创建图实例并运行工作流    graph = JavaVerifierGraph()    graph.run_workflow(initial_code)    return graphif __name__ == "__main__":    graph = run_code_validation_flow()    # 生成流程图PNG数据(字节形式,适用于非Jupyter环境)    mermaid_png_bytes = graph.get_graph().draw_mermaid_png()    # 指定输出图片文件名    output_filename = "langgraph_workflow.png"    try:        # 以二进制写入模式打开文件        with open(output_filename, "wb") as f:            # 写入图片字节数据            f.write(mermaid_png_bytes)        print(f"流程图已保存至 {output_filename}")    except Exception as e:        print(f"生成流程图时出错:{e}")

核心思路:使用LangGraph时,你通过显式定义状态schema和单个节点(函数)来构建工作流,然后用边连接这些节点。编排逻辑本质上是你构建的一个图,这为你提供了强大但更复杂的状态管理底层工具。

4 结论

我欣赏CrewAI简洁、快速启动的工作流和开发体验,这加速了原型开发和小范围项目的进度。Flow功能增加了一层显式控制,缩小了与底层框架的差距。同时,LangGraph在企业级系统的重量级、可扩展AI管道中表现突出,尤其适合需要完全控制图编排的场景。

要全面理解每个框架的工作流实现能力,还需考虑其他关键方面:状态管理、处理状态持久化(保存和恢复工作流)的能力,以及实现人机协同(HITL)场景的难易程度。这些因素对于设计需要持久性或外部干预的稳健、长期运行的流程至关重要。

最后

为什么要学AI大模型

当下,⼈⼯智能市场迎来了爆发期,并逐渐进⼊以⼈⼯通⽤智能(AGI)为主导的新时代。企业纷纷官宣“ AI+ ”战略,为新兴技术⼈才创造丰富的就业机会,⼈才缺⼝将达 400 万!

DeepSeek问世以来,生成式AI和大模型技术爆发式增长,让很多岗位重新成了炙手可热的新星,岗位薪资远超很多后端岗位,在程序员中稳居前列。

在这里插入图片描述

与此同时AI与各行各业深度融合,飞速发展,成为炙手可热的新风口,企业非常需要了解AI、懂AI、会用AI的员工,纷纷开出高薪招聘AI大模型相关岗位。
在这里插入图片描述
最近很多程序员朋友都已经学习或者准备学习 AI 大模型,后台也经常会有小伙伴咨询学习路线和学习资料,我特别拜托北京清华大学学士和美国加州理工学院博士学位的鲁为民老师给大家这里给大家准备了一份涵盖了AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频 全系列的学习资料,这些学习资料不仅深入浅出,而且非常实用,让大家系统而高效地掌握AI大模型的各个知识点。

这份完整版的大模型 AI 学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费

AI大模型系统学习路线

在面对AI大模型开发领域的复杂与深入,精准学习显得尤为重要。一份系统的技术路线图,不仅能够帮助开发者清晰地了解从入门到精通所需掌握的知识点,还能提供一条高效、有序的学习路径。

img

但知道是一回事,做又是另一回事,初学者最常遇到的问题主要是理论知识缺乏、资源和工具的限制、模型理解和调试的复杂性,在这基础上,找到高质量的学习资源,不浪费时间、不走弯路,又是重中之重。

AI大模型入门到实战的视频教程+项目包

看视频学习是一种高效、直观、灵活且富有吸引力的学习方式,可以更直观地展示过程,能有效提升学习兴趣和理解力,是现在获取知识的重要途径

在这里插入图片描述
光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。
在这里插入图片描述

海量AI大模型必读的经典书籍(PDF)

阅读AI大模型经典书籍可以帮助读者提高技术水平,开拓视野,掌握核心技术,提高解决问题的能力,同时也可以借鉴他人的经验。对于想要深入学习AI大模型开发的读者来说,阅读经典书籍是非常有必要的。
在这里插入图片描述

600+AI大模型报告(实时更新)

这套包含640份报告的合集,涵盖了AI大模型的理论研究、技术实现、行业应用等多个方面。无论您是科研人员、工程师,还是对AI大模型感兴趣的爱好者,这套报告合集都将为您提供宝贵的信息和启示。
在这里插入图片描述

AI大模型面试真题+答案解析

我们学习AI大模型必然是想找到高薪的工作,下面这些面试题都是总结当前最新、最热、最高频的面试题,并且每道题都有详细的答案,面试前刷完这套面试题资料,小小offer,不在话下
在这里插入图片描述

在这里插入图片描述

这份完整版的大模型 AI 学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费

LangGraph 中实现多智能体系统的核心在于利用其图结构来编排和管理多个智能体之间的交互与协作。LangGraph 提供了灵活的状态管理和通信机制,使得开发者能够构建高度可扩展、可交互的多智能体协同系统。 ### 多智能体系统的构建流程 1. **定义状态模型** 在构建多智能体系统之前,首先需要定义一个包含系统中所有状态的数据结构。通常使用 `pydantic` 模型来描述状态对象,例如研究状态(ResearchState)或任务状态(TaskState)。该模型用于在不同节点之间传递和更新数据。 ```python from pydantic import BaseModel from typing import List, Dict class AgentState(BaseModel): task: str agents: Dict[str, str] # 智能体名称到当前状态的映射 results: List[str] ``` 2. **初始化图结构** 使用 `StateGraph` 来创建图,并将状态模型作为参数传入。每个节点代表一个智能体或处理步骤,边则表示它们之间的执行顺序或依赖关系[^3]。 ```python from langgraph.graph import StateGraph workflow = StateGraph(AgentState) ``` 3. **添加节点与边** 每个节点可以是一个函数,代表一个智能体的行为逻辑。通过为节点分配函数并设置连接关系,即可定义智能体间的协作流程。 ```python def agent_one(state: AgentState): # 执行智能体一的任务逻辑 return {"results": ["Agent one completed"]} def agent_two(state: AgentState): # 执行智能体二的任务逻辑 return {"results": ["Agent two completed"]} workflow.add_node("agent_one", agent_one) workflow.add_node("agent_two", agent_two) workflow.add_edge("agent_one", "agent_two") ``` 4. **设置入口点与终止条件** 定义图的起始节点以及可能的结束节点,确保系统能够正确启动并判断何时完成任务。 ```python workflow.set_entry_point("agent_one") workflow.set_finish_point("agent_two") ``` 5. **编译与运行图** 编译完成后,调用图实例并传入初始状态以启动执行流程。 ```python app = workflow.compile() initial_state = AgentState(task="Multi-agent collaboration", agents={}, results=[]) result = app.run(initial_state) print(result) ``` ### 智能体间通信与状态管理 LangGraph 支持多种通信模式,包括同步与异步消息传递、工具调用等。对于多智能体系统来说,合理择通信模式至关重要,尤其是在智能体数量较多时,应考虑如何避免通信延迟和状态冲突 [^2]。LangGraph 的状态管理系统会自动追踪每个节点的输入输出,并确保状态的一致性和可追溯性。 ### 可视化与低代码开发支持 为了降低开发门槛,LangGraph 还支持图形化界面进行流程设计。开发者可以通过可视化工具拖拽节点、配置属性并实时预览执行路径,从而实现低代码甚至无代码的多智能体系统搭建。 ### 自适应学习与容错能力 未来版本中,LangGraph 可集成自适应学习机制,使智能体在运行过程中动态调整协作策略;同时增强系统的容错能力,在部分智能体失效的情况下仍能维持整体功能的稳定性 [^1]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值