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),被 crewaicrewai_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/默认:CrewAgentExecutorlib/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_finalityiterations += 1finally 块中保证计数。
    • _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.AgentExecutorlib/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,调用 AgentReasoningutilities/reasoning_handler.py,未深读)生成 plan 及带 depends_on 依赖图的 TodoList
    • get_ready_todos_method() → 单个就绪 todo 走 execute_todo_sequential(),多个独立就绪 todo 走 execute_todos_parallel()asyncio.gather + 独立子执行器 StepExecutoragents/step_executor.py)。
    • observe_step_result() 依据 agent.planning_config.reasoning_effortlow/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_reasoningcall_llm_and_parse/call_llm_native_tools,本质是同一循环的 Flow 化移植)。
    • max_iter 仍是硬上限(ensure_force_final_answer router,第 1349 行),在 planning 模式下同样生效。

记忆与上下文管理(压缩、长期记忆、会话持久化)

  • 上下文超长处理utilities/agent_utils.py 第 698-1003 行):is_context_length_exceeded() 识别 provider 报的上下文超限错误;handle_context_length() 依据 respect_context_window(默认 True)选择摘要续跑或 SystemExitsummarize_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.jsonsummarize_instruction),多块时用 asyncio.gather 并行摘要,最后把整个消息列表替换为 [system 消息] + [一条合并摘要消息];用户消息上的文件附件会被保留并重新挂到摘要消息上。
  • 新统一 Memorymemory/unified_memory.py,1105 行,取代旧文档中提到的短期/长期/实体三层记忆模型):单一 Pydantic Memory 模型 + 可插拔 StorageBackend(默认 LanceDB,另支持 Qdrant-edge,可经 resolve_memory_storage 自定义)。
    • remember()/remember_many():写入时若未显式给出 scope/categories/importance,由 LLM 推断EncodingFlow,引用但未深读);写入经专用单 worker ThreadPoolExecutor_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.jsonslices.memory 明确警告 agent “上面的记忆是自动选出的可能不完整”,计数/列举类任务应改用记忆检索工具而非直接信任注入片段。

工具体系(定义/调用协议/注册/权限)

  • tools/base_tool.pyBaseTool 是 Pydantic ABC;若未显式提供 args_schema,通过 inspect.signature_run() 方法签名自动推导(_default_args_schema 校验器,第 200-230+ 行);每个子类通过 __init_subclass__(第 109-112 行)自注册进全局 _TOOL_TYPE_REGISTRY(按模块路径为 key),用于从 checkpoint/state 反序列化时解析具体工具类。
    • 字段:namedescriptionenv_vars(声明所需环境变量及说明,轻量 manifest)、args_schemaresult_schemacache_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)。
  • 缓存agents/cache/cache_handler.pyToolsHandler.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_executionget_code_execution_tools()现为 no-op,见沙箱章节);multimodalAddImageToolapps/mcps 字段 → 平台/MCP 工具注入;模型不原生支持的输入文件 → ReadFileTool;解析出任何 memory → create_memory_tools()(recall/remember 工具直接暴露给 LLM)。
  • MCP 支持mcp/client.pymcp/config.pymcp/filters.pymcp/tool_resolver.py,及 3 种 transport(stdio.py/http.py/sse.py)——CrewAI agent 可把外部 MCP server 当工具消费(tools/mcp_tool_wrapper.pytools/mcp_native_tool.py);本轮仅确认目录结构和文件名,未深读内部实现。

Prompt 设计(系统提示结构、动态组装)

  • utilities/prompts.pyPrompts.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/userhitl_distill_system/user)、对话模式系统提示。
  • 自定义 prompt 覆盖Agent 上的 system_template/prompt_template/response_template 字段允许用户用 {{ .System }}/{{ .Prompt }}/{{ .Response }} 占位符整体替换结构(_build_prompt,第 135-181 行)。

Router / 编排(任务分解、多 agent、子 agent)

  • Crew 级(多 agent)crew.pyProcess.sequential(线性任务列表,_execute_tasks)vs Process.hierarchical_create_manager_agent 自动生成一个”Crew Manager” agent,配 AgentTools(agents=self.agents).tools()DelegateWorkTool+AskQuestionToolallow_delegation=True;manager LLM 默认取 manager_llm 或完整的 manager_agent 覆盖)。Process.consensualprocess.py 中是未实现的 # TODO stub
  • _execute_tasks()crew.py 第 1515-1584 行):遍历任务列表;支持逐任务 async_execution(经 task.execute_async 排入 Future,在下一个同步任务前批量收敛);ConditionalTaskcheck_conditional_skip 根据前序输出决定是否跳过;每个任务的 context = 前序任务输出拼接(_get_context)。
  • 单 crew 内的 agent 间委派tools/agent_tools/agent_tools.pyDelegateWorkTool(把子任务分派给某个具名 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、metadata dict、从空格分隔的 allowed-tools frontmatter 字段解析出的 allowed_tools)与 Skill,三级 DisclosureLevelMETADATA=1(仅 name+description)、INSTRUCTIONS=2(完整 SKILL.md 正文)、RESOURCES=3scripts/references/assets/ 子目录编目)。
  • skills/loader.pydiscover_skills():扫描目录下含 SKILL.md 的直接子目录,以 METADATA 级别加载每个,在事件总线上发出 SkillDiscoveryStartedEvent/SkillLoadedEvent/SkillLoadFailedEvent/SkillDiscoveryCompletedEvent
  • Skills 被渲染进 agent 系统提示(而非用户提示)里的 <skills> XML 块以提升 prompt-cache 效率(见 Prompt 设计章节),经 format_skill_context()
  • 存在一套并行/更新的 experimental/skills/ 模块(registry.pycache.pyevents.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_user prompt 调 LLM 提炼出”可泛化的教训”(DistilledLessons Pydantic 模型——一份可复用规则列表,显式要求跳过纯粹的批准或无泛化指导价值的内容),并经 mem.remember_many(lessons, source=learn_source) 存入 Memory 系统。后续运行时 _pre_review_with_lessons() 会向记忆查询”针对 {method_name} 的人类反馈教训”,并用 LLM(hitl_pre_review_system/user prompt)在人类看到下一次输出之前把匹配到的教训应用上去——即”人类纠正 → 提炼规则 → 存入记忆 → 未来输出预先自我修正”的闭环。这是代码库中最明确、最具体的”自我改进”机制。
  • crew.train()crew.py 第 914-961 行):跑 n_iterations 轮,训练期间强制 task.human_input=Trueagent.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_functionguardrail_max_retries 默认 3):一个校验函数/LLM guardrail 对任务输出做检查,失败则把校验错误信息(validation_error i18n 字符串)附回 prompt 重试,直到达到重试上限——这是与上面几个跨 run 机制不同的、单次 run 内的轻量自我修正循环。

可观测性(日志 / trace 格式)

  • 中心事件总线events/event_bus.pyevents/base_events.py)——几乎所有生命周期节点都会发出一个类型化事件;events/types/ 下 20+ 个事件类型模块覆盖 agent/task/crew/llm/memory/tool/mcp/skill/reasoning/observation/checkpoint/a2a/flow/system/env 域。这是日志、控制台输出、tracing 三者共用的唯一事实源。
  • 控制台/日志输出AgentLogsStartedEvent/AgentLogsExecutionEventevents/types/logging_events.py)驱动人类可读的彩色控制台输出(crewai_core.printer.PRINTER),受 agent.verbose/crew.verbose 控制。
  • 结构化 tracingevents/listeners/tracing/TraceEvent(dataclass:event_idtimestamptypeevent_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.pyToolCallHookContext)——注册的钩子可返回 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.pySecurityConfig.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.pyauth/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.pyget_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 实现 BaseLLM ABC,能精确处理各家的结构化输出、原生 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.pystate/checkpoint_listener.pyevents/types/checkpoint_events.py,加上 CLI 支持(checkpoint_cli.pycheckpoint_tui.pyreplay_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.pyagents/planner_observer.pyagents/parser.pyagents/tools_handler.py — 支撑执行器机制(存在性确认,未逐行深读)
    • agent/core.pyagent/planning_config.py
    • crew.py(2360 行,_run_sequential_process/_run_hierarchical_process/_create_manager_agent/_execute_tasks/_prepare_tools/train() 等)
    • process.pyProcess.sequential/hierarchicalconsensual 未实现)
    • task.py(guardrail 重试机制,grep 确认)
    • memory/unified_memory.pymemory/recall_flow.pymemory/encoding_flow.pymemory/memory_scope.pymemory/storage/{lancedb_storage,qdrant_edge_storage,backend,factory}.py
    • utilities/agent_utils.pyutilities/prompts.py
    • translations/en.json
    • tools/base_tool.pytools/structured_tool.pytools/tool_usage.pytools/mcp_tool_wrapper.pytools/mcp_native_tool.pytools/agent_tools/agent_tools.py
    • mcp/client.pymcp/config.pymcp/filters.pymcp/tool_resolver.pymcp/transports/{base,http,sse,stdio}.py
    • hooks/tool_hooks.pyhooks/llm_hooks.pyhooks/decorators.pyhooks/types.pyhooks/wrappers.py
    • security/security_config.pysecurity/fingerprint.pysecurity/constants.py
    • skills/models.pyskills/loader.pyskills/parser.pyskills/validation.pyexperimental/skills/{registry,cache,events,_flag}.py
    • events/event_bus.pyevents/base_events.pyevents/event_listener.pyevents/types/*.pyevents/listeners/tracing/{types.py,trace_batch_manager.py}
    • flow/flow.pyflow/dsl/{_start,_listen,_router,_conditions,_utils,_types}.pyflow/persistence/{base,decorators,factory,sqlite}.pyflow/human_feedback.py
    • utilities/training_handler.pyutilities/training_converter.py
    • core/providers/human_input.py
    • a2a/*.py(18 个文件)
    • llms/base_llm.pyllms/cache.pyllms/providers/{anthropic,azure,bedrock,gemini,openai,openai_compatible,snowflake}/
    • experimental/evaluation/agent_evaluator.py 及同目录其他文件
    • CLI(lib/cli/src/crewai_cli/):cli.pycheckpoint_cli.pycheckpoint_tui.pycrew_chat.pymemory_tui.pytrain_crew.pyreplay_from_task.pyreset_memories_command.pyevaluate_crew.py
    • crewai-core(lib/crewai-core/src/crewai_core/):token_manager.pyauth/providers/keycloak.pyauth/token.py
    • 文档:docs/edge/en/concepts/production-architecture.mdxdocs/edge/en/concepts/planning.mdxdocs/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.pyfiles/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.mdxfiles/doc_planning.mdxfiles/doc_tracing.mdx — 官方设计文档