资讯详情

多智能体协作实战:用CrewAI构建高效AI工作流

📅 2026/10/22 18:15:40 | 华诺云谱 👁 阅读
多智能体协作实战:用CrewAI构建高效AI工作流
我最早听到多智能体协作框架这个概念时第一反应是这不就是把好几个提示词塞进一个循环里跑吗后来自己动手做了一个跨部门Agent协作项目才发现问题远没有这么简单——每个角色要各自维护上下文、要做工具调用、要处理另一个Agent的产出如果全靠手写状态机代码规模会迅速膨胀。我在这条路上试过好几套方案最终在CrewAI上稳定下来。这篇文章不是官方文档的翻译而是我做完几个真实项目后的实战复盘。我会从核心概念讲起给出一个能从0跑通的最小Demo再延伸到生产级团队编排的完整代码最后把我踩过的坑完整复盘一遍。适合刚接触Agent编排的开发者也适合正在评估要不要引入多智能体的技术负责人。看完你至少能判断两件事什么场景值得上CrewAI什么场景硬上纯属自找麻烦。1. 先搞清楚CrewAI到底替你解决了什么问题1.1 多智能体不是多个提示词模板很多人对多智能体的理解停留在多开几个不同的System Prompt然后串起来。这确实是多智能体的雏形但它带来一个关键问题每个角色之间的信息传递、工具使用、任务分工、质量校验都需要你自己写代码管理。项目一复杂代码里全是把A的输出传给BB再调一次模型的胶水逻辑非常难维护。CrewAI做的事情是把一组AI角色围绕一个目标协作完成任务这套模式抽象成了基础设施。它替你管理了这些胶水逻辑谁先做、谁后做、前一个人的输出怎么传给后一个人、什么时候该调用工具、角色之间的记忆怎么共享。你只需要定义有哪些角色、各自什么分工、任务清单是什么、走什么流程剩下的调度由框架完成。这个定位决定了它的适用范围不是所有任务都需要多智能体但凡是需要多个专业角色、多种工具、多个步骤才能交付的任务它就是比裸写提示词循环更省心的方案。1.2 Agent、Task、Crew三个核心对象CrewAI里有三个无论如何都要搞清楚的对象它们是所有例子的基础。对象作用最常见错误Agent定义角色、目标、背景故事、可用工具只给role不给清晰goal和backstoryTask定义要完成的具体任务和期望输出expected_output写写一份报告没有可验证标准Crew把Agent和Task组装起来定义流程并执行只装配任务不指定Process与上下文依赖我习惯把Agent想象成一个入职的员工Task就是派给他的活Crew就是这条业务线的项目组。员工需要知道自己是谁role、要达成什么goal、有什么背景经验backstory、能使用什么工具tools。派活的时候必须告诉他做了什么、做成什么样算好、输出给谁用。这里特别想强调一个参数expected_output。我发现很多初学者栽在它上面Description写了一大段Expected Output却只写一句输出文档。框架和大模型都需要一个可执行的标准越具体越好。比如输出一份包含背景、数据、结论、建议四个章节的800字Markdown报告效果就比写份报告好得多。1.3 Process与Flow编排逻辑别混CrewAI中有两种编排逻辑很多人一开始分不清导致代码写出来行为很怪。Process是Agent之间的协作模式就是Crew内部怎么跑。最简单的是Process.sequential严格按照Task顺序串行执行还有Process.hierarchical会有一个manager Agent相当于项目经理动态分配任务、审核中间结果。层级模式更灵活但token消耗明显更高小任务不建议用。Flow是更高层的编排方式面向的是Crew与Crew之间、任务与任务之间的流程控制。它允许你写事件驱动的流程比如报告生成完成后审核事件触发如果审核不通过走重写分支。Process管的是Crew内部如何协作Flow管的是整个业务流如何流转。一句话总结Process是团队内部怎么开工Flow是整条生产线怎么调度。2. 最小可运行Demo从0到1跑通一个三人写作团队2.1 环境准备Python版本和安装CrewAI本质是一个Python框架所以我默认你已经有Python环境。我推荐Python 3.10以上版本低版本容易在依赖解析上踩坑。安装就一条命令pip install crewai crewai-toolscrewai-tools包含很多现成工具封装如果你只是做最简单的Demo先只装crewai也够用。我的习惯是新建一个干净的虚拟环境再装避免和项目里其他依赖打架。装完可以用pip show crewai确认版本不同版本的API写法会略有差异这篇文章里的代码基于当前主流的0.30以上版本API风格。注意别在全局环境里装。CrewAI的依赖链比较重全局环境很容易出现某个库版本冲突排查起来非常浪费时间。虚拟环境是成本最低的防护措施。2.2 一个Agent加一个Task先确认链路通很多人一上来就复制别人的三智能体协作代码跑不通也不知道是哪一环出了问题。我的建议是先做最小验证一个Agent一个Task确认模型调用、API Key、输出返回都正常再往上加复杂度。下面是最小可运行版本from crewai import Agent, Task, Crew editor Agent( role内容编辑, goal把用户提供的原始素材改写成通顺的中文短文, backstory你有十年的内容编辑经验擅长把杂乱信息整理成清晰的表达。, verboseTrue, ) edit_task Task( description请阅读下面的素材产品上线三周后用户反馈集中在登录慢、界面拥挤、消息推送不及时。请把它改写成一段通顺的产品说明。, expected_output一段150字左右的中文短文要求语句通顺、逻辑清楚。, agenteditor, ) crew Crew( agents[editor], tasks[edit_task], verboseTrue, ) result crew.kickoff() print(result.raw)这段代码跑通之后你就获得了最基本的信心模型能调用、任务能执行、结果能输出。然后再扩展到多Agent协作。我之所以强调这个最小闭环是因为多Agent项目一旦出问题排查链路很长如果把每个Agent都单独验证过后面定位问题会快很多。2.3 扩大到三个Agent研究、写作、校对最小闭环跑通之后加人就有了安全感。这里我们做一个真正意义上的写作小组研究Agent负责收集观点写作Agent负责成文校对Agent负责检查修改。from crewai import Agent, Task, Crew, Process researcher Agent( role行业研究员, goal围绕指定主题收集关键信息和核心观点形成事实清单, backstory你擅长快速检索资料并提炼要点会明确区分事实与主观判断。, verboseTrue, ) writer Agent( role文章撰写者, goal基于研究员提供的事实清单撰写结构清晰的文章初稿, backstory你擅长把要点组织成读者容易理解的文字行文简洁自然。, verboseTrue, ) editor Agent( role校对编辑, goal检查文章的逻辑、语病和格式问题输出修改建议并生成终稿, backstory你以严格细致著称善于发现文章中的含糊表达和结构缺陷。, verboseTrue, ) research_task Task( description围绕远程办公工具的核心痛点这个主题列出5条关键洞察。, expected_output5条关键词洞察每条附带依据和适用范围。, agentresearcher, ) write_task Task( description根据研究员的洞察清单撰写一篇适合行业社区的干货文章。, expected_output一篇600字左右的中文文章包含标题、导语、三个小标题和结语。, agentwriter, ) edit_task Task( description对文章初稿进行校对指出逻辑不通、表达冗余、格式不规范之处。, expected_output先列出问题清单再给出修改后的最终全文。, agenteditor, ) crew Crew( agents[researcher, writer, editor], tasks[research_task, write_task, edit_task], processProcess.sequential, verboseTrue, ) result crew.kickoff() print(result.raw)这个例子里三个Agent按顺序执行前一个任务的输出会自动进入后一个任务执行的上下文。你不需要手动拼接字符串CrewAI已经帮你处理了。从代码上看和单Agent版本相比只是多了几个对象和一条任务链但能力完全不同研究、写作、校对三个环节各司其职。2.4 第一次运行时的观察要点跑通这个三人协作Demo之后建议你别急着关终端多看一眼日志和输出重点观察三件事。第一每个Agent的verbose日志里会显示它接收到了什么上下文。如果写作Agent的日志里没有出现研究员生成的观点清单说明上下文传递出了问题后面就要排查Task的依赖关系。第二观察Agent是否角色失真。很多人会发现写作Agent写得像研究员或者校对Agent变成复读机。这种情况通常不是框架问题而是backstory写得不够有区分度。把角色背景写得越具体输出风格差异越明显。第三看result.raw的最终输出。如果校对Agent只是把初稿原样输出一遍可能是它没有真正发现问题说明expected_output里的要求不够严苛比如没有要求必须列出问题清单再给终稿。我第一次跑这种多人协作Demo时印象最深的是单个Agent的输出质量直接决定了整个链条的输出质量。别指望后面加一个审核Agent就能把前面两个Agent的烂活完全救回来。多智能体不是三个臭皮匠顶个诸葛亮而是每个环节都要靠谱协作才有意义。3. 把这些组件拼进生产环境的完整示例3.1 LLM接入与模型选型Demo阶段随便用默认配置没问题但生产环境一定得把模型接入单独管理。CrewAI支持通过LLM对象统一配置模型服务我会用环境变量把敏感信息隔离开import os from crewai import LLM llm LLM( modelos.getenv(MY_LLM_MODEL, 你的模型标识), base_urlos.getenv(MY_LLM_BASE_URL, ), api_keyos.getenv(MY_LLM_API_KEY, ), )这样所有Agent都可以复用同一个llm实例。如果你用的是兼容标准接口的模型服务只需要把base_url填成对应的服务地址。需要特别留意的是多Agent协作场景强烈依赖工具调用能力你选的模型必须支持这类接口否则Agent无法真正使用Tools只能假装调用这对生产环境是致命的。模型选型上我的经验是研究、分析类Agent用偏低的Temperature0.1到0.3让输出更稳定写作、创意类Agent可以调到0.7左右。同一个模型不一定适合所有Agent有条件的话不同角色可以配不同模型代价是成本更高、维护更复杂。刚开始还是建议统一模型等效果确实卡住了再差异化。3.2 给Agent配Tools真实工作流比纯聊天复杂CrewAI的价值一大半体现在工具调用上。没有工具的Agent只能靠训练知识凭空回答有了工具的Agent才能查资料、算数据、对接内部系统这是抑制幻觉最有效的手段之一。自定义一个工具的代码非常简单from crewai.tools import tool tool(CompanyInfoSearch) def company_info_search(query: str) - str: 搜索指定公司或产品的公开资料返回整理后的文本摘要。 # 实际项目里接入搜索服务或内部资料库 return 这里放搜索结果摘要 tool(TableCalculator) def table_calculator(expression: str) - str: 计算简单的统计量比如增长率、占比等传入可计算的数学表达式。 # 生产环境不要直接用eval建议换成算式解析库 return str(eval(expression))这里有几个细节容易忽略。第一函数的docstring很重要它是Agent判断什么时候该用这个工具的依据写得越清楚工具被正确调用的概率越高。第二一个工具只做一件事不要把搜索、计算、存档全部塞进一个函数里否则Agent会迷茫。第三工具的参数类型和返回值要尽量简单复杂结构会让模型输出格式更不稳定。我给Agent配上工具之后明显感觉输出落地了很多至少关键数字不是模型编的了。3.3 一个完整的生产级Crew竞品分析报告现在把这些东西串成一个完整的例子。假设我们的任务是生成一份竞品分析报告团队由四个Agent组成市场信息采集员、数据分析师、报告撰写人、质量审核员。import os from crewai import Agent, Task, Crew, Process, LLM from crewai.tools import tool llm LLM( modelos.getenv(MY_LLM_MODEL, 你的模型标识), base_urlos.getenv(MY_LLM_BASE_URL, ), api_keyos.getenv(MY_LLM_API_KEY, ), ) tool(CompanyInfoSearch) def company_info_search(query: str) - str: 搜索指定公司或产品的公开资料返回整理后的文本摘要。 return 【搜索结果摘要】这里放真实返回内容 tool(TableCalculator) def table_calculator(expression: str) - str: 计算简单的统计量比如增长率、占比等传入可计算的数学表达式。 return str(eval(expression))research_agent Agent( role市场信息采集员, goal收集指定行业和竞品的最新公开信息整理成事实清单, backstory你擅长从杂乱资料里提取事实并严格标注信息出处。, tools[company_info_search], llmllm, verboseTrue, ) analysis_agent Agent( role数据分析师, goal根据事实清单计算关键指标并给出客观结论, backstory你习惯先核数再说话不编造没有来源的数据。, tools[table_calculator], llmllm, verboseTrue, ) writer_agent Agent( role报告撰写人, goal把分析结论改写成结构清晰、可交付的竞品分析报告, backstory你擅长把零散要点扩展成管理层能直接阅读的中文报告。, llmllm, verboseTrue, ) review_agent Agent( role质量审核员, goal检查报告是否包含必需章节、数据是否有来源、结论是否完整, backstory你以严格著称发现问题必须如实指出不因为对方是AI就放水。, llmllm, verboseTrue, )research_task Task( description围绕目标产品收集至少5条公开信息输出事实清单。, expected_output结构化清单包含产品名称、发布时间、用户评价、市场活动等字段每条注明来源。, agentresearch_agent, ) analysis_task Task( description基于采集到的事实清单计算关键指标并输出3条明确结论。, expected_output结论列表每条结论必须附计算过程和原始数据来源。, agentanalysis_agent, context[research_task], ) write_task Task( description将分析结论扩展成完整报告包含背景、数据、结论、建议四个章节。, expected_output不少于600字的竞品分析报告使用Markdown格式。, agentwriter_agent, context[analysis_task], ) review_task Task( description按清单逐项检查报告输出是否通过并列出不符合项。, expected_output通过或不通过以及需要修正的具体清单。, agentreview_agent, context[write_task], ) crew Crew( agents[research_agent, analysis_agent, writer_agent, review_agent], tasks[research_task, analysis_task, write_task, review_task], processProcess.sequential, verboseTrue, ) result crew.kickoff() print(result.raw)这段代码里有一个容易被忽略但极其重要的点context参数。数据分析师的任务必须依赖采集员的结果报告撰写人必须依赖分析师的结论所以我在创建Task时用context显式声明了依赖关系。虽然Process.sequential本来就会串行执行但显式声明上下文可以让信息传递更明确也不会因为调整了Task顺序就断了链路。运行这个Crew之后你会得到一个基本完整的报告框架。生产环境里我会把打印出来的raw内容存成Markdown文件而不是只输出到控制台。3.4 跑完之后的控制循环验证与人工兜底上面的流程有一个明显缺口质量审核员是最一个环节它说不通过之后系统并没有自动重写。真实项目里不可能只生成一版就交付所以需要做一层验证循环。最简单的方式是用Python在Crew外面控制for attempt in range(3): result crew.kickoff() print(f第 {attempt 1} 轮生成完成) if 通过 in result.raw: print(质量达标进入交付流程) break else: print(多次生成仍未达标转人工处理)这比在Crew框架内部做复杂跳转要稳定得多。很多团队一开始想把重写循环塞进CrewAI的Flow里但Flow的调试成本更高外部循环反而直观、可控、可测试。等确实需要复杂条件分支、多Crew编排时再考虑Flows也不迟。质量验证的核心是定义什么叫通过。我记得第一版项目里审核Agent的要求写得模棱两可结果它每次都回通过搞得我很高兴后来仔细一看报告全是废话。后来我把检验标准改成硬性指标必须包含四个章节、每章至少指定字数、数据必须附来源、结论必须能对应到前面的分析。指标越硬循环验证越有意义。3.5 数据落地别让输出只停留在命令台这个建议看起来简单但我真见过不少项目把所有结果都打印到终端重启就丢了。生产环境至少要跑完输出到文件with open(report.md, w, encodingutf-8) as f: f.write(result.raw)同时可以把每个Task的中间输出也落盘。比如采集员的事实清单、分析师的结论列表分别存成facts.md、analysis.md。这样万一报告出问题你能回溯到具体环节而不是只能看到最终结果。我也建议把运行日志和每次调用的成本记录下来。CrewAI的verbose日志已经含了很多信息但成本统计需要自己在外面包一层。每次调用前记录一下请求量和token数两周之后你就会有一张很有说服力的多智能体成本报表这个在向团队说明技术选型时非常有用。4. 实战中容易踩的坑附排查链路4.1 问题一Agent之间信息断档A不知道B说了什么表现前一个Agent明明产出了大量内容后一个Agent却像失忆一样重新说了一遍车轱辘话。原因通常有两种。一种是Task之间没有建立依赖关系尤其是你用了多个Agent但Task的context没写后一个Task自然拿不到前一个Task的输出。另一种是前一个Agent的输出太杂乱后一个Agent拿到上下文之后不知道哪个部分对自己有用。我的排查习惯是先看verbose日志。日志里会显示每个Agent收到的上下文内容如果日志里没有前一个任务的输出那就是依赖没建立去检查Task的context。如果上下文有但效果差那就去优化前一个任务的expected_output让它输出更结构化、更聚焦。比如从一段文字改成编号列表后一个Agent的利用率会明显上升。4.2 问题二输出JSON被截断、格式错乱多智能体项目中我很喜欢让某个Agent输出结构化数据比如JSON供后续其他Agent或下游系统消费。最常见的问题是模型输出了一段JSON但前后多了解释性文字或者中途截断直接导致json.loads失败。解决方案有三个层级。第一在expected_output里把要求写死只输出JSON不要添加任何解释文字不要使用Markdown代码块。第二在Task上使用结构化管理。第三也是更稳定的就是用外部校验兜底无论模型输出什么你做一层解析解析失败就重跑或者转人工。import json def parse_task_output(text: str) - dict: start text.find({) end text.rfind(}) 1 if start -1 or end 0: raise ValueError(未找到JSON边界) return json.loads(text[start:end])这种截取法算是我在实际项目里最常用的兜底方案。模型输出再乱只要有花括号先截出来试试解析成功率很高。同时给Task配上max_tokens可以降低写到一半截断的概率但要注意别因为限制太少导致后半段内容缺失。4.3 问题三Agent假装完成任务幻觉式交付这是最隐蔽也最坑的问题。表面上所有Agent都成功完成了输出也有模有样但数据是编的、结论站不住脚。最典型的场景数据分析师没有真正计算直接说按增长率30%估算。为什么会出现因为模型没有足够强的依据来拒绝回答它更倾向于顺着上下文编一个合理答案。要解决这个问题我不指望模型自觉而是从两个方向下手第一关键数字必须通过工具获取配了计算工具就要引导它用工具用说明和上下文约束第二加审核Agent时明确要求所有数字必须能追溯到来源没有来源的标注为待核实。审核Agent也许会漏但加上这个硬要求之后至少大问题能被拦下一批。还有一个土办法让Agent先输出数据来源清单再输出结论。如果第二阶段看到的结论在第一阶段来源清单里完全找不到基本可以判定有幻觉成分。这个办法简单但真的有效。4.4 问题四Token成本暴涨一个任务吃掉一堆额度多Agent框架的成本通常比单Agent高一个量级。因为每个Agent都带自己的上下文前序任务输出又不断往后传token消耗是叠加的。我见过一个团队做月度报告Crew一次跑完花费感人结果效果还不如人工。控制成本有几个非常实用的策略一是控制单个Task的输出长度让中间Agent只输出要点不要长篇大论真正长篇输出留给最后的写作Agent二是限制Agent的max_iter有些Agent会反复自我修正一次任务调十几次模型三是及时清理不必要的记忆和历史记录四是对可缓存的检索结果做缓存别每次都重新搜索。给大家一个成本对照表方便检查自己的配置常见浪费点表现对策中间Task输出过长研究Agent直接写了2000字把expected_output改成要点列表Agent反复自我迭代max_iter设置太高普通任务限制3轮以内上下文重复携带每层任务都带完整历史精简Task描述结构化传递关键信息工具重复调用同一搜索执行多次加缓存或结果复用4.5 排查多Agent问题的通用步骤如果你遇到一个特别诡异的协作问题别盯着最终输出猜原因按顺序排查。第一步固定模型、固定Temperature保证每次运行可复现。第二步把每个Agent单独拎出来喂一份人工准备的标准输入看它的输出是否符合预期。第三步确认Task依赖链从日志看上下文有没有正确传递。第四步简化流程把四个Agent砍成两个如果问题消失基本就是流程协作问题而不是模型问题。我有个深刻的教训有一次审核Agent总是奇奇怪怪我调了好几天Prompt最后发现是研究Agent输出的格式极其混乱把审核Agent的上下文污染了。所以排查顺序一定是从前到后而不是逮着最后结果死磕。5. 关于落地再说几句真心话5.1 哪些场景真的需要多智能体我做了几个真实项目之后总结出一个判断标准任务是否存在多个专业角色、多种工具、多轮校验且这些环节之间有明确的信息传递关系。符合这个标准的典型场景包括研究报告生成、市场调研分析、复杂内容创作、客服工单分级加回复、需要调用多种数据源生成结果的业务报告。在这些场景里多智能体不是炫技而是实实在在把复杂任务拆解成了可控制、可验收的环节。还有一个更实际的价值可评估。单Agent输出一大坨好坏边界模糊多Agent每个环节都有交付物哪个环节弱就优化哪个环节这对技术团队非常友好。5.2 哪些场景别用CrewAI硬凑说句得罪人的话有些项目真不需要多智能体。比如简单的文本摘要、单一问答、结构固定的单轮RAG查询一个Agent甚至一段Prompt就能干得很好。你硬拆成三个Agent花销翻倍、延迟变长、还多了一堆潜在的失败节点。判断标准也很简单如果一个任务你用一个Agent加一次工具调用就能完成就不要拆成三个。多智能体的收益在于拆解拆解是需要成本的成本不只是token还包括调试时间和系统复杂度。我曾经把一个本来5秒出结果的客服问答硬套CrewAI结果延迟拉到20多秒效果还很尴尬后来果断退回单Agent方案。诚实一点说CrewAI最适合的场景是你已经确认单Agent搞不定了而不是别人都在用多智能体所以我也要上。5.3 团队引入CrewAI的节奏建议如果你是在技术团队里推这个方案我的建议是分三步走。第一步选一个高频但复杂度适中的任务做试点比如日报生成或周报汇总。先让团队每个人都能跑通最小Demo。第二步把生产流程中的关键角色和任务清单固定下来形成一套模板不要每次从零开始调Prompt。第三步建立质量监控和成本监控的机制用真实数据决定是否扩展到更多业务。最后分享一个我的个人习惯每次新建Crew我都会先写一份任务说明书把每个Agent的目标、输入、输出、验证标准写清楚再写代码。这份说明书不是形式主义它就是后续调试的对照表。很多项目出了问题回头一看才发现是当初任务定义就没写清楚。先想清楚每个环节要交付什么再让代码去实现能少走很多弯路。
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑