CrewAI
一句话定位
CrewAI 是一个以”多 agent 协作(Crew)+ 有状态编排(Flow)“为核心卖点的开源 Python 框架,代码库目前处于新旧交替期:默认仍是经典 ReAct 文本循环执行器,但已经用 Flow 状态机重写出一个真正的 Plan-and-Execute 执行器(experimental.AgentExecutor),同时把 memory、skills、A2A 协议、tracing 都做成了独立子系统;核心开源代码不含沙箱,官方明确建议接第三方沙箱服务。
核心架构总览(目录结构关键路径 + 引用的 commit)
仓库现为 monorepo,顶层 lib/ 下拆分为多个包(引用 commit 2b90117e887ef68a22ccf9552a58ffaf96de1fc4,2026-07-02,clone 于 2026-07-07):
lib/crewai/src/crewai/— 主框架包crewai,本次调研的主战场lib/crewai-core/src/crewai_core/— 底层共享工具(printer、token manager、auth providers),被crewai和crewai_cli共用lib/crewai-tools/src/crewai_tools— 预制工具包(搜索、文档、代码、AWS Bedrock code interpreter 等)lib/cli/src/crewai_cli/—crewai命令行入口lib/crewai-files— 文件/多模态附件处理lib/devtools— 开发工具docs/edge/en/— 最新未发布版官方文档(Mintlify/MkDocs 风格.mdx)
内部按功能拆出的关键子目录:agents/(两套执行器)、memory/(新 unified_memory.py)、tools/(BaseTool + MCP 客户端)、flow/(DSL + 持久化)、skills/ 与 experimental/skills/(两套并存的技能实现)、a2a/(跨进程 Agent-to-Agent 协议)、events/(统一事件总线)、hooks/(工具/LLM 调用钩子)、security/(Fingerprint + SecurityConfig)、llms/providers/(per-vendor 原生 SDK 客户端,非 litellm)。
Agent Loop(主循环 / 何时继续何时停)
两套执行器并存:
-
legacy/默认:
CrewAgentExecutor(lib/crewai/src/crewai/agents/crew_agent_executor.py,__init__中显式抛DeprecationWarning,第 143-155 行,但仍是Crew绑定 agent 的默认执行器)。invoke()→_invoke_loop()(第 309 行):依据llm.supports_function_calling()与是否存在original_tools,二选一走 ReAct 文本模式或原生 tool-calling 模式。_invoke_loop_react()(第 330 行):while not isinstance(formatted_answer, AgentFinish);每轮检查has_reached_max_iterations超限则强制给出最终答案;process_llm_response()解析 ReAct 文本Action:/Final Answer:为AgentAction/AgentFinish;工具执行经execute_tool_and_check_finality;iterations += 1在finally块中保证计数。_invoke_loop_native_tools()(第 484 行):同样的停止条件逻辑但用原生 tool-call 对象;若 provider 中途报”不支持原生 tool calling”错误会自动降级回 ReAct 文本模式(is_native_tool_calling_unsupported_error,第 576-579 行)。- 并行工具调用:
_handle_native_tool_calls(第 667-807 行),当一批 tool call 数 >1 且都没有result_as_answer/max_usage_count限制时,用ThreadPoolExecutor(max_workers=min(8, N))并发执行,随后拼一条post_tool_reasoning(i18n slice)合成 user 消息让模型统一反思所有结果。 - 停止条件汇总:(a) LLM 给出
AgentFinish;(b) 达到max_iter强制终答;(c) 某工具result_as_answer=True时其输出直接作为最终答案(第 1097-1106 行);(d)OutputParserError触发有界重试;(e) 上下文超长时按respect_context_window决定摘要续跑还是SystemExit。
-
新:
experimental.AgentExecutor(lib/crewai/src/crewai/experimental/agent_executor.py,约 3200 行)——重写为crewai.flow.Flow状态机(同时继承Flow[AgentExecutorState]与BaseAgentExecutor),是一个真正的 Plan-and-Execute 架构,docstring 明确引用 “PLAN-AND-ACT Section 3.3”(第 617 行):generate_plan()(@start(),第 309 行):若agent.planning_enabled,调用AgentReasoning(utilities/reasoning_handler.py,未深读)生成 plan 及带depends_on依赖图的TodoList。get_ready_todos_method()→ 单个就绪 todo 走execute_todo_sequential(),多个独立就绪 todo 走execute_todos_parallel()(asyncio.gather+ 独立子执行器StepExecutor,agents/step_executor.py)。observe_step_result()依据agent.planning_config.reasoning_effort(low/medium/high)路由到三种不同的后处理策略:low 仅启发式通过/失败检查,无额外 LLM 调用,仅在硬失败时重规划;medium 调PlannerObserver.observe()(LLM 判断),仅失败时重规划;high 做完整决策路由,可通过goal_achieved提前退出(GoalAchievedEarlyEvent)、触发replan_now,或做轻量的refine_and_continue(只微调剩余 todo 描述而不整体重规划)。- 动态重规划(
_should_replan/_trigger_replan,第 2447-2585 行):触发条件为 ≥2 个失败 todo、≥2 个错误结果 todo,或 LLM 输出中出现”need to reconsider”/“try a different approach”类措辞;由planning_config.max_replans(默认 3)设上限;重规划时保留已完成 todo 的结果(replace_pending_todos)。 planning_enabled=False时退化为与 legacy 执行器相同的 ReAct/原生 tool-call 机制(initialize_reasoning→call_llm_and_parse/call_llm_native_tools,本质是同一循环的 Flow 化移植)。max_iter仍是硬上限(ensure_force_final_answerrouter,第 1349 行),在 planning 模式下同样生效。
记忆与上下文管理(压缩、长期记忆、会话持久化)
- 上下文超长处理(
utilities/agent_utils.py第 698-1003 行):is_context_length_exceeded()识别 provider 报的上下文超限错误;handle_context_length()依据respect_context_window(默认True)选择摘要续跑或SystemExit。summarize_messages():先把非 system 消息按 token 预算切块(_split_messages_into_chunks,约 4 字符/token 的启发式,对照llm.get_context_window_size()),每块用专门的”结构化摘要” prompt 总结(Task Overview / Current State / Important Discoveries / Next Steps / Context to Preserve,包在<summary>标签内,见translations/en.json的summarize_instruction),多块时用asyncio.gather并行摘要,最后把整个消息列表替换为[system 消息] + [一条合并摘要消息];用户消息上的文件附件会被保留并重新挂到摘要消息上。 - 新统一
Memory类(memory/unified_memory.py,1105 行,取代旧文档中提到的短期/长期/实体三层记忆模型):单一 PydanticMemory模型 + 可插拔StorageBackend(默认 LanceDB,另支持 Qdrant-edge,可经resolve_memory_storage自定义)。remember()/remember_many():写入时若未显式给出 scope/categories/importance,由 LLM 推断(EncodingFlow,引用但未深读);写入经专用单 workerThreadPoolExecutor(_save_pool)异步/后台执行,_pending_saves追踪,drain_writes()会在recall()前自动调用(读后写屏障)。recall():depth="shallow"(直接向量检索)或默认depth="deep"(跑RecallFlow:LLM 把查询拆成子查询、选定 scope、并行检索,并按exploration_budget/confidence_threshold_high/low/complex_query_threshold做置信度路由的可选深挖轮次)。- 综合相关性打分 = 时效(指数衰减,半衰期可配)+ 语义相似度 + 重要性的加权组合(
compute_composite_score)。 - 分层 scope(形如
/crew/research/...路径),MemoryScope/MemorySlice视图,private/source字段支持按用户可见性过滤——内建多租户记忆分区。 consolidation_threshold/consolidation_limit:写入时对近似重复记忆做去重合并。- 注:这是一个真正 LLM-in-the-loop 的记忆系统,内部编码/召回分析调用自己的 LLM,代码里默认写的是
gpt-5.4-mini(第 89 行)——这是 clone 时刻仓库依赖的字面字符串,不代表真实已发布模型名,如实记录。
- 会话/Flow 状态持久化:
flow/persistence/{sqlite.py,base.py,decorators.py}——@persist装饰器(production-architecture.mdx中文档化)按 UUID 保存 Flow 状态;kickoff(inputs={"id": <uuid>})恢复;restore_from_state_id可从某历史状态 fork 出新分支而不延续原有历史。 - 记忆注入 prompt 时的反幻觉提示:
translations_en.json→slices.memory明确警告 agent “上面的记忆是自动选出的可能不完整”,计数/列举类任务应改用记忆检索工具而非直接信任注入片段。
工具体系(定义/调用协议/注册/权限)
tools/base_tool.py:BaseTool是 PydanticABC;若未显式提供args_schema,通过inspect.signature从_run()方法签名自动推导(_default_args_schema校验器,第 200-230+ 行);每个子类通过__init_subclass__(第 109-112 行)自注册进全局_TOOL_TYPE_REGISTRY(按模块路径为 key),用于从 checkpoint/state 反序列化时解析具体工具类。- 字段:
name、description、env_vars(声明所需环境变量及说明,轻量 manifest)、args_schema、result_schema、cache_function(按调用决定是否可缓存)、result_as_answer(工具输出直接作为最终答案,跳过后续推理)、max_usage_count/current_usage_count(执行器强制的硬用量上限)。
- 字段:
- 调用协议两套并行:
- ReAct 文本模式:LLM 输出
Action: <name>/Action Input: <json>文本,由agents/parser.py(未深读)解析为AgentAction,经execute_tool_and_check_finality分发。 - 原生模式:LLM 输出 OpenAI/Anthropic/Gemini 原生 tool-call 对象;
convert_tools_to_openai_schema()/setup_native_tools()(utilities/agent_utils.py)把注册工具转成 OpenAI function-calling JSON schema;_execute_single_native_tool_call()(crew_agent_executor.py第 868-1071 行)负责逐调用分发、缓存(tools_handler.cache)、前后置钩子、事件发射(ToolUsageStartedEvent/ToolUsageFinishedEvent/ToolUsageErrorEvent)。
- ReAct 文本模式:LLM 输出
- 缓存:
agents/cache/cache_handler.py(ToolsHandler.cache)按(tool_name, input_str)缓存工具结果,执行前先查缓存;cache_function决定某次调用+结果是否值得缓存。 - 注册/权限:工具挂在
Agent/Task/Crew层级;Crew._prepare_tools()(crew.py第 1602 行)按 task 动态增补 agent 工具列表:allow_delegation→ 加DelegateWorkTool/AskQuestionTool(hierarchical 流程下为 manager 专属工具);allow_code_execution→get_code_execution_tools()(现为 no-op,见沙箱章节);multimodal→AddImageTool;apps/mcps字段 → 平台/MCP 工具注入;模型不原生支持的输入文件 →ReadFileTool;解析出任何 memory →create_memory_tools()(recall/remember 工具直接暴露给 LLM)。 - MCP 支持:
mcp/client.py、mcp/config.py、mcp/filters.py、mcp/tool_resolver.py,及 3 种 transport(stdio.py/http.py/sse.py)——CrewAI agent 可把外部 MCP server 当工具消费(tools/mcp_tool_wrapper.py、tools/mcp_native_tool.py);本轮仅确认目录结构和文件名,未深读内部实现。
Prompt 设计(系统提示结构、动态组装)
utilities/prompts.py—Prompts.task_execution()(第 74-115 行)按顺序拼接”slice”:固定的role_playing(“You are {role}. {backstory}\nYour personal goal is: {goal}”)+ 二选一的tools(含Action:/Action Input:格式规范的 ReAct 指令)或no_tools,再加任务类型 slice(task/native_task/task_no_tools)。- Skill 块注入(
_build_skill_block,第 117-133 行):agent 已激活的 Skills 被渲染成稳定的<skills>...</skills>XML 块,附加在系统提示(system prompt)而非用户/任务提示——源码内注释明确写明设计意图:“Skills are agent-scoped (do not change per task), so they live in the system prompt where prompt-cache prefixes can survive across calls”,是刻意的 prompt-cache 成本优化。 - Prompt-cache 断点:
crew_agent_executor.py._setup_messages()(第 170-206 行)显式在 system 消息末尾与 user 消息末尾调用mark_cache_breakpoint(),注释说明:“end-of-system caches the per-agent stable prefix; end-of-user caches the per-task stable prefix across ReAct-loop iterations”。llms/cache.py实现了这个 provider 无关的标记;各 provider adapter 负责翻译(例如转成 Anthropic 的cache_control块)或对不支持/隐式缓存的 provider 直接剥离。 - 所有字面 prompt 文本集中在
translations/en.json(i18n 设计,本轮只读了en.json,其他 locale 未确认)的slices/errors/tools顶层键下——包含 ReAct 格式指令、post_tool_reasoning提示(原生工具调用后使用,要求”只给答案不要元评论”)、记忆注入反幻觉警告、HITL 反馈与 lesson 提炼 prompt(hitl_pre_review_system/user、hitl_distill_system/user)、对话模式系统提示。 - 自定义 prompt 覆盖:
Agent上的system_template/prompt_template/response_template字段允许用户用{{ .System }}/{{ .Prompt }}/{{ .Response }}占位符整体替换结构(_build_prompt,第 135-181 行)。
Router / 编排(任务分解、多 agent、子 agent)
- Crew 级(多 agent):
crew.py—Process.sequential(线性任务列表,_execute_tasks)vsProcess.hierarchical(_create_manager_agent自动生成一个”Crew Manager” agent,配AgentTools(agents=self.agents).tools()即DelegateWorkTool+AskQuestionTool,allow_delegation=True;manager LLM 默认取manager_llm或完整的manager_agent覆盖)。Process.consensual在process.py中是未实现的# TODOstub。 _execute_tasks()(crew.py第 1515-1584 行):遍历任务列表;支持逐任务async_execution(经task.execute_async排入Future,在下一个同步任务前批量收敛);ConditionalTask经check_conditional_skip根据前序输出决定是否跳过;每个任务的 context = 前序任务输出拼接(_get_context)。- 单 crew 内的 agent 间委派:
tools/agent_tools/agent_tools.py—DelegateWorkTool(把子任务分派给某个具名 coworker agent)与AskQuestionTool(问 coworker 一个问题而不做完整任务委派),二者都动态绑定到 crew 内其他 agent 列表。 - Flow 编排(跨 crew / 有状态流水线):
flow/flow.py+flow/dsl/{_start,_listen,_router,_conditions}.py— 事件驱动 DAG,@start()、@listen(method_or_label)、@router(method_or_label)(按标签分支到不同后继)、or_()/and_()多前驱汇合组合子。新的experimental.AgentExecutor本身就是用Flow实现的(见 Agent Loop 章节)——同一套 DSL 现在同时驱动跨 crew 流水线和单 agent 内部控制流。 - A2A(跨进程 agent-to-agent):
a2a/包 — 完整协议实现(agent card 及签名utils/agent_card_signing.py、客户端/服务端认证方案、扩展注册表、委派工具),使 CrewAI agent 可作为标准化 A2A 远程 agent 被暴露或消费——与 crew 内委派工具是不同的机制。
Skill / 插件体系
- CrewAI 实现了一套直接对标 Anthropic “Agent Skills” 规范的原生 Skills 系统(SKILL.md + YAML frontmatter + 渐进式披露):
skills/models.py定义SkillFrontmatter(name、description、license、compatibility、metadatadict、从空格分隔的allowed-toolsfrontmatter 字段解析出的allowed_tools)与Skill,三级DisclosureLevel:METADATA=1(仅 name+description)、INSTRUCTIONS=2(完整 SKILL.md 正文)、RESOURCES=3(scripts/、references/、assets/子目录编目)。 skills/loader.py的discover_skills():扫描目录下含SKILL.md的直接子目录,以 METADATA 级别加载每个,在事件总线上发出SkillDiscoveryStartedEvent/SkillLoadedEvent/SkillLoadFailedEvent/SkillDiscoveryCompletedEvent。- Skills 被渲染进 agent 系统提示(而非用户提示)里的
<skills>XML 块以提升 prompt-cache 效率(见 Prompt 设计章节),经format_skill_context()。 - 存在一套并行/更新的
experimental/skills/模块(registry.py、cache.py、events.py、_flag.py)——可能是重写中或功能开关变体,本轮未深读,标记为待后续研究的开放问题。 - Skills 与”工具”的区分:工具是 LLM 经 function-calling 调用的单个可调用体;skills 是打包好的指令+脚本+资源的较大单元,按需渐进式加载进上下文——这与 Claude Code / Claude Skills 语义高度一致。
自进化能力(自我改进 / 学习型记忆 / eval 驱动纠错)
发现三种独立机制——均不修改模型权重,全部是上下文内/存储制品层面的反馈闭环:
- HITL lesson 提炼(
flow/human_feedback.py,全文件读完):人类审阅/纠正某次 Flow 输出后,_distill_and_store_lessons()用hitl_distill_system/hitl_distill_userprompt 调 LLM 提炼出”可泛化的教训”(DistilledLessonsPydantic 模型——一份可复用规则列表,显式要求跳过纯粹的批准或无泛化指导价值的内容),并经mem.remember_many(lessons, source=learn_source)存入Memory系统。后续运行时_pre_review_with_lessons()会向记忆查询”针对 {method_name} 的人类反馈教训”,并用 LLM(hitl_pre_review_system/userprompt)在人类看到下一次输出之前把匹配到的教训应用上去——即”人类纠正 → 提炼规则 → 存入记忆 → 未来输出预先自我修正”的闭环。这是代码库中最明确、最具体的”自我改进”机制。 crew.train()(crew.py第 914-961 行):跑n_iterations轮,训练期间强制task.human_input=True且agent.allow_delegation=False,收集每 agent 每轮的(initial_output, human_feedback, improved_output)三元组(CrewTrainingHandler,pickle 存储),再跑TaskEvaluator(agent).evaluate_training_data()生成trained_data["suggestions"]列表存文件。之后的正式运行中Agent._use_trained_data()(agent/core.py第 1199 行)读回该文件,把建议前置拼进任务 prompt(apply_training_data,第 535 行)——本质是 prompt 前缀式的 few-shot/“指令调优”,不是权重训练。experimental.evaluation.AgentEvaluator:订阅事件总线上的TaskCompletedEvent/LiteAgentExecutionCompletedEvent,对每个完成的任务跑可插拔BaseEvaluator实现,产出AgentEvaluationResult/AgentAggregatedEvaluationResult。这是一套 eval 打分框架;未观察到其结果自动反馈进 agent 行为(没有发现自动重训闭环)——更像人类可见的质量看板而非自动纠错路径。evaluation_listener.py/base_evaluator.py未深读,若需要更深入结论要留待后续。- Task guardrail 有界重试(
task.py的_invoke_guardrail_function/_ainvoke_guardrail_function,guardrail_max_retries默认 3):一个校验函数/LLM guardrail 对任务输出做检查,失败则把校验错误信息(validation_errori18n 字符串)附回 prompt 重试,直到达到重试上限——这是与上面几个跨 run 机制不同的、单次 run 内的轻量自我修正循环。
可观测性(日志 / trace 格式)
- 中心事件总线(
events/event_bus.py、events/base_events.py)——几乎所有生命周期节点都会发出一个类型化事件;events/types/下 20+ 个事件类型模块覆盖 agent/task/crew/llm/memory/tool/mcp/skill/reasoning/observation/checkpoint/a2a/flow/system/env 域。这是日志、控制台输出、tracing 三者共用的唯一事实源。 - 控制台/日志输出:
AgentLogsStartedEvent/AgentLogsExecutionEvent(events/types/logging_events.py)驱动人类可读的彩色控制台输出(crewai_core.printer.PRINTER),受agent.verbose/crew.verbose控制。 - 结构化 tracing:
events/listeners/tracing/—TraceEvent(dataclass:event_id、timestamp、type、event_data,以及 DAG 关联字段parent_event_id/previous_event_id/triggered_by_event_id/emission_sequence)。TraceBatchManager/TraceBatch把事件攒批后经plus_api.initialize_trace_batch()/initialize_ephemeral_trace_batch()POST 到后端——这是 CrewAI 自家的托管 SaaS tracing 后端(CrewAI AMP/Enterprise,app.crewai.com),不是 OpenTelemetry 或任何开放 trace 标准。docs/edge/en/observability/tracing.mdx确认:需要crewai login(OAuth device-code 流程)才能启用,trace 在 app.crewai.com 查看。first_time_trace_handler.py暗示有首次运行时引导启用 tracing 的提示。 - 本次调研未在核心包中发现内置 OpenTelemetry/Jaeger/本地文件 trace 导出(
crewai-tools或企业版代码里是否有未核实,超出本次范围)。
安全与权限(审批门、密钥管理)
- 审批门:
before_tool_call钩子(hooks/tool_hooks.py,ToolCallHookContext)——注册的钩子可返回False直接阻断某次工具调用,执行器会用一条合成的”Tool execution blocked by hook”结果替代实际执行(crew_agent_executor.py第 954-979 行,experimental/agent_executor.py的原生工具路径中有对应实现)。after_tool_call钩子可对执行结果字符串做事后改写。还有对称的before_llm_call/after_llm_call钩子对(hooks/llm_hooks.py,未深读),用于检查/改写 LLM 消息——对应production-architecture.mdx文档化的”LLM Hooks”控制原语。 - agent 身份/指纹:
security/security_config.py—SecurityConfig.fingerprint(一个Fingerprint对象,推测基于 UUID+时间戳,未深读)挂在每个 agent 上,作为agent_fingerprint上下文传入工具执行(两套执行器中均可见)。该类自己的 docstring 明确把 Authentication credentials、Scoping rules、Impersonation/delegation tokens 列为*TODO*——即 CrewAI 自己的代码承认这些尚未实现,目前真正落地的只有 fingerprint/identity 这一部分。 - 凭证存储:
crewai_core.token_manager.TokenManager(见关键文件)——Fernet 对称加密的 OAuth token 落盘,平台特定的安全目录(macOS 上~/Library/Application Support/crewai/credentials),0o700/0o600权限强制,原子写入(tempfile +os.replace)——这套机制服务于crewai login(用于 CrewAI AMP/Enterprise 认证,而非用户提供的模型 API key,后者按代码库其他地方标准的 litellm/provider 惯例走明文环境变量)。 - OAuth2 支持:
auth/oauth2.py、auth/providers/{auth0,entra_id,keycloak,okta,workos}.py— 可插拔的企业级 SSO provider,推测服务于 CrewAI AMP/Enterprise 登录而非终端用户的 agent 鉴权。 - 除上述粗粒度的 hook 审批门外,未发现针对工具访问的 RBAC/细粒度权限系统。
沙箱与执行隔离
本次调研在该 commit 下确认核心开源代码没有内置沙箱,明确的废弃证据:
agent/core.py第 237-241 行:allow_code_execution: bool | None字段,deprecated=True,说明文字:“Deprecated. CodeInterpreterTool is no longer available. Use dedicated sandbox services instead.”agent/core.py第 263-267 行:code_execution_mode: Literal["safe","unsafe"],同样deprecated=True,同一说明文字。agent/core.py的get_code_execution_tools()(第 1166-1174 行):现在直接返回[]并抛DeprecationWarning:“CodeInterpreterTool is no longer available. Use dedicated sandbox services like E2B or Modal.”- 在
lib/crewai-tools/src/crewai_tools下未找到任何基于 Docker 或子进程的代码执行工具(对docker/Docker做过 grep,无命中);唯一的”code_interpreter”命中是 AWS Bedrock 专用工具包(aws/bedrock/code_interpreter/),它把沙箱执行完全委托给 AWS Bedrock 的托管代码解释器服务,而非本地实现隔离。 - 结论:CrewAI 官方推荐(据其自己的废弃说明)是把第三方沙箱提供商(E2B、Modal)作为外部工具接入;开源核心本身不提供也不维护沙箱能力。
与模型的协同设计
- 各厂商原生 SDK 客户端(未走 litellm 路由):
llms/providers/{anthropic,azure,bedrock,gemini,openai,openai_compatible,snowflake}/— 每个都直接对着厂商 SDK 实现BaseLLMABC,能精确处理各家的结构化输出、原生 tool calling、多模态、stop word 等差异化能力,而非走最小公分母垫片。BaseLLM.supports_function_calling()/supports_stop_words()/supports_multimodal()/get_context_window_size()是执行器用来选择 ReAct-vs-原生策略以及上下文管理行为的能力探测面。 - 面向 prompt-cache 的设计:
llms/cache.py的断点标记 +_setup_messages()中明确的 system/user 拆分(见 Prompt 设计章节)是第一优先级的设计考量——消息结构专门为了在 ReAct 循环多轮之间、以及带 skill 的系统提示之间最大化前缀缓存命中率。 - 客户端侧 stop-word 模拟:
base_llm.py的_apply_stop_words()—— 对于原生 SDK 不支持stop参数(或 CrewAI 自家原生封装未透传)的 provider,客户端侧通过查找最早出现的配置 stop 字符串来截断响应。这是为了在 stop-sequence 支持参差不齐的各 provider 间维持 ReAct 格式解析可靠性的兼容垫片。 - 规划 LLM 默认值与执行 LLM 解耦:
Crew(planning=True)文档(planning.mdx)注明默认规划 LLM 是gpt-4o-mini,与任务 agent 实际使用的模型无关——一个显式的设计选择,把(更便宜的、元层面的)规划模型与(可能更贵/更专用的)执行模型解耦。
轨迹利用(session/trajectory 是否反哺训练/评测)
- Flow 状态持久化:
flow/persistence/{sqlite.py,decorators.py}+@persist装饰器 — Flow 执行状态(一个 Pydantic 模型)按flow_uuid持久化保存;kickoff(inputs={"id": <uuid>})恢复一个进行中或已完成 Flow 的历史;restore_from_state_id可从某历史状态数据 fork 出新分支而不延续原有的持久化历史。这是进程崩溃恢复/长时运行工作流续跑,不是 eval/训练数据。 - checkpoint 系统:
state/checkpoint_config.py、state/checkpoint_listener.py、events/types/checkpoint_events.py,加上 CLI 支持(checkpoint_cli.py、checkpoint_tui.py、replay_from_task.py)——crew.py引用checkpoint_kickoff_event_id从指定点恢复任务执行(_get_execution_start_index)。这是 CrewAI 的”从任务 N 重放某次 crew 运行”功能——用于调试/迭代的轨迹重放,不是自动重训。 - 训练数据复用:如自进化章节所述,
crew.train()的输出(每 agent 建议列表的 pickle 文件)在运行时被读回提示词中(Agent._use_trained_data)——轨迹确实被复用了,但纯粹作为上下文内的 few-shot 引导,从未作为基于梯度的微调数据或评测基准构建素材。核心包中未发现将 CrewAI 轨迹导出为面向下游模型微调格式的机制(没有 OpenAI fine-tuning JSONL 导出器,没有 RL/DPO trace 格式)。 - Tracing 数据:上传到 CrewAI AMP/Enterprise(见可观测性章节),推测用于托管看板自身的分析;本代码库中未发现供用户把自己的 trace 数据拉回本地 eval 或训练流水线的公开/开源机制(需要核实 AMP/Enterprise 产品本身,超出本次 OSS 源码阅读范围)。
与同类 harness 的关键差异(1-3 条,可以先留一句概述,后续 synthesis 阶段会做跨 harness 对比)
- CrewAI 是本轮调研中少见的”新旧执行器并存”案例:默认仍是 ReAct 文本循环(
CrewAgentExecutor),但已经在experimental.AgentExecutor中用Flow状态机重写出引用了 “PLAN-AND-ACT” 论文思想的 Plan-and-Execute 架构,且这套 Flow DSL 同时服务于跨 crew 编排和单 agent 内部控制流——这种”用同一套状态机 DSL 同时表达 macro 编排和 micro 执行循环”的设计在同类框架中较为独特。 - 自进化机制的最强证据是 HITL lesson 蒸馏闭环(
flow/human_feedback.py),而非权重训练或 eval 驱动的自动纠错——crew.train()和AgentEvaluator都更偏向人类可见的辅助工具而非自动化闭环,这与部分强调”轨迹自动反哺训练”的 harness 形成对比。 - 沙箱能力被官方主动阉割(
allow_code_execution/code_execution_mode全部标记 deprecated,get_code_execution_tools()直接返回[]),转向依赖 E2B/Modal 等第三方沙箱服务,与一些自带 Docker/gVisor 沙箱的 harness 形成鲜明对比;具体跨 harness 对比留待 synthesis 阶段。
原始源码定位
- repo: https://github.com/crewAIInc/crewAI
- commit/version analyzed:
2b90117e887ef68a22ccf9552a58ffaf96de1fc4(2026-07-02 14:28:01 -0700,clone/读取于 2026-07-07) - 关键文件列表(相对
lib/crewai/src/crewai/除非另注明):agents/crew_agent_executor.py— legacy ReAct 执行器experimental/agent_executor.py— 新 Flow-based Plan-and-Execute 执行器agents/step_executor.py、agents/planner_observer.py、agents/parser.py、agents/tools_handler.py— 支撑执行器机制(存在性确认,未逐行深读)agent/core.py、agent/planning_config.pycrew.py(2360 行,_run_sequential_process/_run_hierarchical_process/_create_manager_agent/_execute_tasks/_prepare_tools/train()等)process.py(Process.sequential/hierarchical;consensual未实现)task.py(guardrail 重试机制,grep 确认)memory/unified_memory.py、memory/recall_flow.py、memory/encoding_flow.py、memory/memory_scope.py、memory/storage/{lancedb_storage,qdrant_edge_storage,backend,factory}.pyutilities/agent_utils.py、utilities/prompts.pytranslations/en.jsontools/base_tool.py、tools/structured_tool.py、tools/tool_usage.py、tools/mcp_tool_wrapper.py、tools/mcp_native_tool.py、tools/agent_tools/agent_tools.pymcp/client.py、mcp/config.py、mcp/filters.py、mcp/tool_resolver.py、mcp/transports/{base,http,sse,stdio}.pyhooks/tool_hooks.py、hooks/llm_hooks.py、hooks/decorators.py、hooks/types.py、hooks/wrappers.pysecurity/security_config.py、security/fingerprint.py、security/constants.pyskills/models.py、skills/loader.py、skills/parser.py、skills/validation.py、experimental/skills/{registry,cache,events,_flag}.pyevents/event_bus.py、events/base_events.py、events/event_listener.py、events/types/*.py、events/listeners/tracing/{types.py,trace_batch_manager.py}flow/flow.py、flow/dsl/{_start,_listen,_router,_conditions,_utils,_types}.py、flow/persistence/{base,decorators,factory,sqlite}.py、flow/human_feedback.pyutilities/training_handler.py、utilities/training_converter.pycore/providers/human_input.pya2a/*.py(18 个文件)llms/base_llm.py、llms/cache.py、llms/providers/{anthropic,azure,bedrock,gemini,openai,openai_compatible,snowflake}/experimental/evaluation/agent_evaluator.py及同目录其他文件- CLI(
lib/cli/src/crewai_cli/):cli.py、checkpoint_cli.py、checkpoint_tui.py、crew_chat.py、memory_tui.py、train_crew.py、replay_from_task.py、reset_memories_command.py、evaluate_crew.py - crewai-core(
lib/crewai-core/src/crewai_core/):token_manager.py、auth/providers/keycloak.py、auth/token.py - 文档:
docs/edge/en/concepts/production-architecture.mdx、docs/edge/en/concepts/planning.mdx、docs/edge/en/observability/tracing.mdx
一手源存档(sources/)
/Users/zhao/projects/self-wiki/ai-research/sources/harness/crewai/ 下:
NOTES.md— 本次调研的完整逐维度笔记(含文件路径/行号)files/crew_agent_executor.py— legacy ReAct 执行器全文files/agent_executor_experimental.py— 新 Flow-based Plan-and-Execute 执行器全文(约 3200 行)files/unified_memory.py— 新Memory类全文files/prompts.py— prompt 组装逻辑全文files/translations_en.json— 全部 i18n prompt 模板files/skills_models.py、files/skills_loader.py— Agent Skills 实现files/hooks_tool_hooks.py— 工具调用钩子/审批门上下文files/flow_human_feedback.py— HITL + lesson 蒸馏自我改进闭环全文files/token_manager.py— 加密凭证存储全文(来自 crewai-core)files/agent_tools.py— 多 agent 委派工具接线files/llms_cache.py— prompt-cache 断点标记全文files/doc_production-architecture.mdx、files/doc_planning.mdx、files/doc_tracing.mdx— 官方设计文档