关于 check-crewai-api
面向编写或审查 CrewAI 代码的开发者,汇总 CrewAI 1.15.x 的实际 API 字段、导入路径和运行行为,并指出常见的静默失效问题。
主要功能
- 01核对 Agent、Task 与 Crew 参数
- 02提供当前导入路径示例
- 03说明启动与结果读取方式
- 04辨析结构化输出配置
- 05列出 LLM 提供方配置要求
适用场景
- 01升级 CrewAI 后检查代码兼容性
- 02排查无效参数导致的静默问题
- 03配置结构化任务输出
- 04验证 MCP 工具连接写法
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ crewaiinc/ skills --skill check-crewai-api安装后在 Claude Code 中输入/check-crewai-api确认已加载。
附带文件references/source-receipts.mdreferences/verify-installed-api.md
详细介绍
检查 CrewAI API
在编写或审查 crewai 代码前加载本文:它将你可能记得的内容与 crewai 1.15.x 实际接受的内容对应起来。
已于 2026-10-01 根据 crewai 1.15.22 和 1.15.23 验证。
已于 2026-10-01 使用真实 LLM 进行实时测试。
先运行 crewai version;如果主版本号或次版本号与 1.15 不同,请先使用 ask-docs 技能重新验证与版本相关的条目,再采信这些内容。
1. 编写任何内容前,请牢记三条规则
-
未知的关键字参数会被静默忽略。
Agent、Task和Crew会接受并丢弃不存在的参数。Crew(memory_config={...})和Task(response_format=Model)可以正常构造,但不会执行任何操作。过时的参数名称不会触发错误,因此请检查参数是否存在:from crewai import Agent, Crew, Task assert "response_model" in Task.model_fields # real field assert "response_format" not in Task.model_fields # silently dropped if passed assert "memory_config" not in Crew.model_fields # silently dropped if passed print(sorted(Agent.model_fields)[:5]) -
已安装的源代码优先于任何文档、教程或记忆。 这也包括
crewai create在新项目中生成的AGENTS.md。遇到下方与当前任务相关的条目时,请检查已安装版本的签名(参见 verify-installed-api.md)。 -
在边界处断言结构化输出。 下方列出的几种错误会静默失败,导致
out.pydantic is None,但运行仍会报告成功。
2. 导入
| 你可能写过的内容 | 当前 1.15.x 写法 | 错误写法的后果 |
|---|---|---|
from crewai_tools import BaseTool, tool | from crewai.tools import BaseTool, tool | ImportError: cannot import name 'BaseTool' from 'crewai_tools' |
from crewai.flow.flow import Flow, start, listen, persist | from crewai.flow import Flow, start, listen, router, or_, and_, persist | ImportError: cannot import name 'persist' |
from crewai.task import ConditionalTask | from crewai.tasks.conditional_task import ConditionalTask | ImportError |
from crewai.memory import ShortTermMemory, LongTermMemory, EntityMemory | from crewai import Memory | ImportError(这些类已被移除) |
from crewai.utilities.events import crewai_event_bus | from crewai.events import BaseEventListener, crewai_event_bus | ModuleNotFoundError: No module named 'crewai.utilities.events' |
from crewai_tools import CodeInterpreterTool | crewai 中没有替代项——请使用沙箱工具或服务 | ImportError(已移除) |
当前的顶层和项目导入:
from crewai import Agent, BaseLLM, Crew, CrewOutput, Flow, LLM, Memory, Process, Task, TaskOutput
from crewai.project import CrewBase, after_kickoff, agent, before_kickoff, crew, llm, task, tool
from crewai.tools import BaseTool, tool
from crewai.flow import Flow, and_, listen, or_, persist, router, start
from crewai.knowledge.source.string_knowledge_source import StringKnowledgeSource
from crewai.mcp import MCPServerHTTP, MCPServerSSE, MCPServerStdio
from crewai.events import BaseEventListener, crewai_event_bus
3. Agent、Task、Crew 参数及默认值
| 参数 | 当前值 | 说明 |
|---|---|---|
Task.expected_output | 必填 | 单独使用 Task(description=...) 会引发 ValidationError ... expected_output Field required |
Agent.max_iter | 25 | 不要假设是 15 或 20 |
Agent.llm | None -> 构造时解析 | 从环境变量 MODEL、MODEL_NAME、OPENAI_MODEL_NAME 依次读取,否则使用 gpt-4.1-mini |
Agent.cache | True | 只表示允许缓存,并不会启用缓存 |
Crew.cache | False | 工具结果缓存需显式启用:设置 Crew(cache=True) |
Crew.memory | False | |
Crew.process | Process.sequential | 只有 sequential 和 hierarchical |
Task.guardrail_max_retries | 3 | max_retries 已弃用(DeprecationWarning) |
| 你可能写了 | 当前写法 | 错误写法的后果 |
|---|---|---|
Process.consensual | Process.sequential 或 Process.hierarchical | AttributeError |
没有管理者的 Crew(process=Process.hierarchical, ...) | 添加 manager_llm="openai/gpt-4.1-mini" 或 manager_agent=... | ValidationError: Attribute manager_llm or manager_agent is required |
Crew(memory=True, memory_config={...}) | Crew(memory=Memory(...)) | memory_config 会被静默忽略 |
Agent(allow_code_execution=True) / code_execution_mode="unsafe" | 删除;改用沙盒工具 | 已弃用且无效果;allow_code_execution=True 会发出 DeprecationWarning |
Crew(function_calling_llm=...) | 删除,或为每个 Agent 设置 llm | 已弃用,会发出 DeprecationWarning |
两个 async_execution=True 的任务使用同一个 agent | 每个并发异步任务使用一个 Agent | RuntimeError: Executor is already running. Cannot invoke the same executor instance concurrently. |
from crewai import Agent, Crew, Process, Task
researcher = Agent(
role="Researcher",
goal="Find facts about {topic}",
backstory="A careful researcher.",
llm="openai/gpt-4.1-mini",
)
research = Task(
description="List three facts about {topic}.",
expected_output="Three bullet points.",
agent=researcher,
)
crew = Crew(agents=[researcher], tasks=[research], process=Process.sequential, cache=True)
out = crew.kickoff(inputs={"topic": "honey bees"})
print(out.raw)
4. 运行 crew 并读取结果
| 你可能写了 | 当前写法 | 错误写法的后果 |
|---|---|---|
crew.kickoff("honey bees") | crew.kickoff(inputs={"topic": "honey bees"}) | TypeError: inputs must be a dict or Mapping, got str |
使用 await crew.kickoff_async(...) 实现原生异步 | await crew.akickoff(...) | 可以运行,但 kickoff_async 会在线程中运行同步的 kickoff(asyncio.to_thread) |
result.output / result.final_output / result.result | result.raw | AttributeError: 'CrewOutput' object has no attribute ... |
在同一个 Crew 上先调用 crew.kickoff(...),再调用 crew.kickoff_for_each(...) | 为 kickoff_for_each 创建一个新的 Crew(或在任何 kickoff 调用之前调用它) | 不会报错,但每次运行都会复用第一次 kickoff 的输入:每次运行的副本会保留已插值的任务文本 |
在 crew 运行中调用 await crew.akickoff() 时使用 Agent(mcps=["https://..."]) | 使用 mcps=[MCPServerHTTP(url="https://...")](来自 crewai.mcp) | 不会报错,但 Agent 不会获得任何 MCP 工具:字符串引用会调用 asyncio.run() 进行解析,而在运行中的事件循环内会失败(参见 connect-tools-and-mcp) |
CrewOutput 字段:raw、pydantic、json_dict、tasks_output(TaskOutput 列表)、token_usage。out["field"] 会从 pydantic/json_dict 中读取。kickoff_for_each(inputs=[...]) 会返回 CrewOutput 列表。
token_usage 是对每个 Agent 的 LLM 对象在该对象整个生命周期内的用量进行汇总,而非按每次运行统计。两个 Agent 共享同一个 LLM(...) 实例时,每次调用都会被计数两次;同一个实例在多个 crew 之间复用时,也会累计之前 crew 的 token(使用 anthropic/claude-haiku-4-5 验证:在同一个 LLM 上运行第二个仅调用一次的 crew,报告了 148 个 token 和 2 次请求;使用全新的 LLM 则报告 73 个 token 和 1 次请求)。若要统计每次运行的成本,请为每个 crew 使用各自的 LLM 对象,或统计 LLMCallCompletedEvent(event.usage)。
import asyncio
from crewai import Agent, Crew, Task
def make_crew() -> Crew:
writer = Agent(role="Writer", goal="Write", backstory="Writes short text.", llm="openai/gpt-4.1-mini")
task = Task(description="One line on {topic}.", expected_output="One line.", agent=writer)
return Crew(agents=[writer], tasks=[task])
out = make_crew().kickoff(inputs={"topic": "bees"})
print(out.raw, out.token_usage.total_tokens, [t.raw for t in out.tasks_output])
many = make_crew().kickoff_for_each(inputs=[{"topic": "bees"}, {"topic": "ants"}])
print([o.raw for o in many])
async def main():
return await make_crew().akickoff(inputs={"topic": "wasps"})
print(asyncio.run(main()).raw)
5. 大模型、模型字符串和提供商扩展
LiteLLM 不再是依赖项。LLM(model=...) 是一个工厂,会返回原生提供商类;只有 OpenAI SDK 随 crewai 核心包一起提供。
| 你可能写过的形式 | 当前形式 | 错误形式会导致的问题 |
|---|---|---|
安装了普通 crewai 时使用 llm="anthropic/claude-sonnet-4-5" | 执行 uv add "crewai[anthropic]",然后使用相同的字符串 | ImportError: Anthropic native provider not available, to install: uv add "crewai[anthropic]" |
使用普通 crewai 时使用 llm="gemini/gemini-2.5-flash" | 执行 uv add "crewai[google-genai]" | ImportError: Google Gen AI native provider not available |
llm="groq/llama-3.3-70b-versatile"(或 mistral/...、任何非原生提供商) | 执行 uv add "crewai[litellm]" | ImportError: Unable to initialize LLM with model '...'. The model did not match any supported native provider (...), and the LiteLLM fallback package is not installed. |
不设置 llm=,并假定默认值是 gpt-4 | 默认值为 gpt-4.1-mini;设置 MODEL=... 或 llm= | |
llm.call(messages, response_format=Model) | llm.call(messages, response_model=Model) | TypeError: ... unexpected keyword argument 'response_format'. Did you mean 'response_model'? |
自定义 BaseLLM.call(self, messages, tools=None, callbacks=None, available_functions=None) | 还需接受 from_task=None, from_agent=None, response_model=None(或 **kwargs) | 启动时出现 TypeError: call() got an unexpected keyword argument 'from_task' |
原生提供商:openai、anthropic/claude、azure、google/gemini、bedrock/aws、openrouter、deepseek、ollama、hosted_vllm、cerebras、dashscope、snowflake。扩展:crewai[anthropic]、crewai[google-genai]、crewai[bedrock]、crewai[azure-ai-inference]、crewai[litellm]。构造时不会检查密钥;启动时才会检查(ValueError: OPENAI_API_KEY is required 或 ANTHROPIC_API_KEY is required;密钥错误时会收到提供商返回的 AuthenticationError ... 401)。crewai create 生成的脚手架不会添加提供商扩展,即使使用了 --provider anthropic/... 也不会:请自行运行 uv add "crewai[anthropic]"。
from crewai import LLM
gpt = LLM(model="openai/gpt-4.1-mini", temperature=0.2) # core install
local = LLM(model="ollama/llama3") # core install, OpenAI-compatible route
claude = LLM(model="anthropic/claude-sonnet-4-5") # needs: uv add "crewai[anthropic]"
print(type(gpt).__name__, type(local).__name__, type(claude).__name__)
自定义 LLM 需继承 BaseLLM,并使用完整签名实现 call。如果 call 会将 messages 转发给提供商 SDK,只发送每条消息的 role 和 content:crewai 会在部分消息中添加 cache_breakpoint: True 键,而 Anthropic API 会因此拒绝请求,并返回 400 ... messages.0.cache_breakpoint: Extra inputs are not permitted。
from typing import Any
from crewai import Agent, BaseLLM, Crew, Task
class EchoLLM(BaseLLM):
def call(self, messages, tools=None, callbacks=None, available_functions=None,
from_task=None, from_agent=None, response_model=None, **kwargs: Any) -> str:
return "echo: " + str(messages[-1]["content"])[:40]
agent = Agent(role="Echo", goal="Echo", backstory="Echoes.", llm=EchoLLM(model="echo"))
task = Task(description="Say hi", expected_output="Anything", agent=agent)
print(Crew(agents=[agent], tasks=[task]).kickoff().raw)
6. 结构化输出
| 位置 | 用途 | 结果存放位置 |
|---|---|---|
Task(output_pydantic=Model) | 任务和团队输出中的解析后模型 | out.pydantic、out["field"] |
Task(output_json=Model) | 字典输出 | out.json_dict |
Task(response_model=Model) | 仅使用提供方原生结构化输出 | out.raw(JSON 文本);out.pydantic 保持为 None |
Agent.kickoff(messages, response_format=Model) | 独立 Agent | LiteAgentOutput.pydantic |
llm.call(messages, response_model=Model) | 直接调用大模型 | 解析后的模型 |
LLM(model=..., response_format=Model) | 构造函数级默认值 |
| 你可能写的是 | 当前写法 | 错误写法的结果 |
|---|---|---|
Task(response_format=Model) | Task(output_pydantic=Model) | 被静默忽略 |
Agent.kickoff(msg, response_model=Model) | Agent.kickoff(msg, response_format=Model) | TypeError: ... Did you mean 'response_format'? |
Task(output_pydantic=M, output_json=M) | 二选一 | ValidationError: Only one output type can be set |
Task(output_pydantic=M, output_file="report.md"),并期望文件中是正文 | 移除 output_pydantic,或自行渲染模型 | 文件中会写入模型的 JSON,不受扩展名影响 |
output_file="/abs/path/report.md" | 使用相对路径(或通过输入设置 output_file="{out_dir}/report.md") | 开头的 / 会被移除,因此文件会存放在当前目录下 |
tasks.yaml 中的 output_pydantic: Report | 在 Python 的 @task 方法中设置 output_pydantic=Report | 没有匹配的 @output_pydantic 类时:KeyError: 'Report'。有匹配项时:会被静默丢弃,out.pydantic is None |
from pydantic import BaseModel
from crewai import Agent, Crew, Task
class Report(BaseModel):
title: str
points: list[str]
analyst = Agent(role="Analyst", goal="Summarise", backstory="Concise.", llm="openai/gpt-4.1-mini")
task = Task(description="Summarise {topic}.", expected_output="A title and points.",
agent=analyst, output_pydantic=Report)
out = Crew(agents=[analyst], tasks=[task]).kickoff(inputs={"topic": "bees"})
assert out.pydantic is not None, "structured output was dropped"
print(out.pydantic.title, out["points"])
standalone = analyst.kickoff("Summarise bees.", response_format=Report)
print(standalone.pydantic)
在 @CrewBase 项目中,即使任务的其他部分使用 YAML,也要将模型保留在 Python 中:
@task
def research_task(self) -> Task:
return Task(config=self.tasks_config["research_task"], output_pydantic=Report)
7. 护栏
函数护栏接收一个参数(TaskOutput),并返回一个元组 (bool, value)。当结果为 False 时,该值会作为错误反馈给 Agent,任务会重试,最多重试 guardrail_max_retries 次(默认值为 3);之后任务会引发 Task failed guardrail validation after N retries。字符串护栏会通过额外的大模型调用进行检查。
| 你可能写的是 | 当前写法 | 错误写法的结果 |
|---|---|---|
def g(out) -> bool: return True | def g(out: TaskOutput) -> tuple[bool, Any],并返回 (True, out.raw) | 有注解:在 Task(...) 处出现 ValidationError: If return type is annotated, it must be Tuple[bool, Any]。无注解:在 kickoff 时出现 TypeError: cannot unpack non-iterable bool object |
-> tuple[bool, object] | -> tuple[bool, Any](或 str、TaskOutput) | 在 Task(...) 处出现相同的 ValidationError |
Task(max_retries=2) | Task(guardrail_max_retries=2) | DeprecationWarning |
依赖 HallucinationGuardrail | 编写函数护栏 | 在开源版 crewai 中,它不起作用,总是通过 |
from typing import Any
from crewai import Agent, Crew, Task, TaskOutput
def under_50_words(output: TaskOutput) -> tuple[bool, Any]:
if len(output.raw.split()) > 50:
return (False, "Keep it under 50 words.")
return (True, output.raw)
writer = Agent(role="Writer", goal="Write", backstory="Brief.", llm="openai/gpt-4.1-mini")
task = Task(description="Describe {topic}.", expected_output="A short paragraph.", agent=writer,
guardrails=[under_50_words, "Must not mention prices"], guardrail_max_retries=2)
print(Crew(agents=[writer], tasks=[task]).kickoff(inputs={"topic": "bees"}).raw)
guardrails=[...] 会按顺序运行每个护栏;成功的字符串结果会替换 out.raw,供下一个护栏使用。
8. 记忆与知识
记忆由一个 Memory 类负责(使用 LanceDB 存储)。默认设置会调用 OpenAI:使用 text-embedding-3-large 生成嵌入,使用 gpt-5.4-mini 进行分析。Crew(memory=True) 则改用第一个 Agent 的 llm 进行分析;知识未指定 embedder 时,会使用 text-embedding-3-small 生成嵌入。使用有效的 OpenAI 密钥实测:一个 memory=True 的 crew 在一个进程中存储了代号,新建的 crew 在下一个进程中成功回忆起该代号;crew 和 Agent 的知识也都能根据来源给出回答。
| 你可能写过 | 当前写法 | 错误写法会导致什么 |
|---|---|---|
ShortTermMemory()、LongTermMemory()、EntityMemory() | Memory(...) | ImportError |
未设置(或设置了无效的)OPENAI_API_KEY 时使用 Crew(memory=True) | 设置密钥,或传入 Memory(llm=..., embedder=...) | Crew 仍会完成运行;所有保存操作都会静默失败(只会发出 MemorySaveFailedEvent),不会存储任何内容 |
未设置密钥时调用 memory.remember(...) | 同上 | RuntimeError: Memory requires an embedder for vector search(密钥无效时:AuthenticationError ... 401) |
在 crew 中使用未设置密钥或 embedder 的 Agent(knowledge_sources=[...]) | 在 Agent 或 Crew 上传入 embedder={...} | crew 启动时出现 ValueError: Invalid Knowledge Configuration: The OPENAI_API_KEY environment variable is not set.(密钥无效时:AuthenticationError ... 401) |
对带有 knowledge_sources 的 Agent 调用 agent.kickoff(...) | 将 Agent 作为任务在 Crew 中运行,或将事实写入提示词 | 无论是否设置密钥都不会报错:Agent.kickoff() 从不查询 Agent 知识,因此回答会忽略这些知识 |
未设置密钥或 embedder 时使用 Crew(knowledge_sources=[...]) | 同上 | 日志会显示 Failed to upsert documents;crew 运行时没有知识 |
在一次运行已存储知识后更改知识的 embedder | 运行 crewai reset-memories -kn(或 crew.reset_memories(command_type="knowledge")),然后再运行 | Embedding function conflict: new: <x> vs persisted: openai;crew 运行时没有知识 |
知识已存储且未指定 embedder 时添加 embedder={"provider": "openai"}(或更改 OpenAI 嵌入模型) | 同样先重置 | Failed to upsert documents: Collection expecting embedding with dimension of 1536, got 3072(显式指定 provider 时,默认使用 text-embedding-3-large);crew 回答时不会使用其知识 |
embedder 配置格式为 {"provider": <name>, "config": {...}};OpenAI 模型对应的键是 model_name。在 Memory 中使用 "model" 会引发 TypeError: ... unexpected keyword argument 'model';用于知识时则会被静默忽略(crew 会使用 text-embedding-3-large 生成嵌入)。下文的 ollama provider 还需要运行 uv add ollama,并启动已拉取模型的 Ollama 服务;如果未安装该软件包,crew 的知识会静默变为 None。{"provider": "onnx"} 是一种本地、无需密钥的 embedder,core crewai 已可直接运行它(使用 chromadb 的 onnxruntime;首次使用时会下载约 80 MB 的模型)——design-agent 技能的记忆与知识参考中有可用示例。在测试中使用确定性 embedder 时,可使用可调用对象(Memory)或自定义类(知识)——请参阅 verify-installed-api.md。
from crewai import Agent, Crew, Memory, Task
from crewai.knowledge.source.string_knowledge_source import StringKnowledgeSource
embedder = {"provider": "ollama", "config": {"model_name": "nomic-embed-text"}} # needs: uv add ollama
memory = Memory(llm="openai/gpt-4.1-mini", embedder=embedder)
facts = StringKnowledgeSource(content="acme was founded in 2020.")
agent = Agent(role="Analyst", goal="Answer", backstory="Uses knowledge.", llm="openai/gpt-4.1-mini")
task = Task(description="When was acme founded?", expected_output="A year.", agent=agent)
crew = Crew(agents=[agent], tasks=[task], memory=memory, knowledge_sources=[facts], embedder=embedder)
if crew.knowledge is None:
print("knowledge failed to initialise - is the ollama package installed and the server running?")
在项目目录中使用 crewai reset-memories -m 重置已存储的数据(重置记忆;如果 crew 没有记忆,则会报错 Memory memory system is not initialized);使用 -kn 重置知识,使用 -akn 重置 Agent 知识,使用 -k 重置最近一次 kickoff 的输出,使用 -a 重置全部数据。旧版 -s、-l、-e 标志是隐藏的弃用别名,会发出警告并重置统一记忆。存储路径和离线 embedder:请参阅 verify-installed-api.md。
9. 项目脚手架和 CLI
| 你可能写的是 | 当前形式 | 错误形式的后果 |
|---|---|---|
crewai create crew my_crew,期望生成 crew.py + YAML | crewai create crew my_crew --classic | 启动交互式向导,生成 JSON 项目(crew.jsonc、agents/*.jsonc);没有 TTY 时会打印 Aborted!。只需要 crew 的脚本应使用 --classic --skip-provider。 |
在 CI 或脚本中对 JSON crew 运行 crewai run | 对于 CI,使用 crewai create crew <name> --classic 创建 crew,并使用 uv run run_crew 运行 | 打开全屏运行视图并等待用户退出,即使没有 TTY 也一样,因此命令永远不会退出。环境变量 CREWAI_DMN=1 曾可在 crewai 1.15.x 中跳过运行视图,但它不受支持且未记录;行为可能会改变 |
在没有 OPENAI_API_KEY 时,保留 JSON 脚手架中的 "memory": true | 设置密钥、将 "memory": false,或配置 embedder | crew 会完成运行;记忆回忆和保存会静默失败 |
对 classic crew 使用 crewai run --inputs '{...}' | 将输入放在 main.py 的 run() 中 | Error: --inputs is only supported for declarative flows and crews |
crewai reset-memories -s -l -e | crewai reset-memories -m | 使用已弃用的别名,并打印警告 |
从 main.run() 返回 crew.kickoff(...) | 不要返回输出 | run_crew 脚本会调用 sys.exit(<CrewOutput>),并在运行成功后以状态码 1 退出;crewai run 会打印 An error occurred while running the crew: ... non-zero exit status 1 |
在 CI 中信任 classic crew(--classic)或 Python flow 的 crewai run 退出码 | 运行 uv run run_crew(退出码会传递)或检查输出 | 在这种情况下,即使 crew 或 flow 进程失败,crewai run 也会以状态码 0 退出;JSON(向导)crew 没有 run_crew 脚本,因此创建 CI crew 时请使用 --classic |
crewai version
crewai create crew research_crew --classic --skip-provider
cd research_crew && uv add "crewai[anthropic]" # only if an agent uses an anthropic/ model
crewai install && crewai run
crewai reset-memories --help
classic 布局:src/<name>/crew.py(@CrewBase 类)、src/<name>/config/agents.yaml 和 tasks.yaml(键与 @agent/@task 方法名匹配)、main.py,以及包含 [tool.crewai] type = "crew" 和依赖项 crewai[tools] 的 pyproject.toml。在 YAML 中,llm: <name> 会解析为同名的 @llm 方法,否则会将其用作模型字符串。crewai create flow 也会生成一个包含占位符 OPENAI_API_KEY 的 .env——请替换它,切勿提交。
10. 已移除和已弃用
| 功能 | 1.15.22-1.15.23 中的状态 | 应改用 |
|---|---|---|
CodeInterpreterTool | 已从 crewai_tools 中移除 | 沙箱工具或服务 |
Agent(allow_code_execution=...)、code_execution_mode | 已弃用,无操作 | 同上 |
ShortTermMemory、LongTermMemory、EntityMemory、memory_config | 已移除/忽略 | Memory(...) |
crewai.utilities.events | 已移除 | crewai.events |
Crew(function_calling_llm=...) | 已弃用 | 按 Agent 设置 llm |
Task(max_retries=...) | 已弃用 | guardrail_max_retries |
crewai.cli 模块 | 弃用兼容层 | crewai_cli(CLI 是独立的软件包) |
| LiteLLM 作为核心依赖 | 可选扩展 | 仅对非原生提供商使用 crewai[litellm] |
11. 常见错误
| 症状 | 原因 | 修复方法 |
|---|---|---|
| 参数不起作用,也没有报错 | Agent/Task/Crew 会丢弃未知的 kwargs | 检查 "name" in Task.model_fields |
out.pydantic is None | 在 YAML 中设置了 output_pydantic,或使用了 response_model 而非 output_pydantic | 在 Python 中设置 output_pydantic=Model;断言其非 None |
ImportError: ... native provider not available | 缺少提供商 SDK 扩展 | uv add "crewai[anthropic]"(或 [google-genai]、[bedrock]、[litellm]) |
启动时出现 ValueError: OPENAI_API_KEY is required | 未设置 llm=,因此使用了默认的 gpt-4.1-mini | 设置 llm= 或 MODEL,并设置提供商密钥 |
| Crew 已完成,但没有记住任何内容 | 设置了 memory=True,但未提供嵌入器密钥 | 传入 Memory(embedder=...) 或设置密钥;监听来自 crewai.events 的 MemorySaveFailedEvent |
| 提示词中始终没有出现知识 | Crew 级知识嵌入失败 | 设置 embedder=;查找 Failed to upsert documents |
TypeError: ... unexpected keyword argument 'from_task' | 自定义的 BaseLLM.call 使用了旧签名 | 接受 from_task、from_agent、response_model、**kwargs |
在 Task(...) 处出现 Tuple[bool, Any] ValidationError | Guardrail 的注解为 -> bool 或 tuple[bool, object] | 注解为 -> tuple[bool, Any],并返回一个元组 |
crewai create crew 卡住或打印 Aborted! | 现在它是交互式 JSON 向导 | 使用 --classic 采用 @CrewBase 布局;在 CI 和脚本中使用 |
JSON crew 的 crewai run 始终不返回 | 运行视图会等待按键 | 对于 CI,使用 crewai create crew <name> --classic,并搭配 uv run run_crew |
kickoff_for_each 的结果都回答了第一个主题 | Crew 已经启动过 | 每个批次都构建一个新的 Crew |
token_usage 大于本次运行可能用到的数量 | 多个 Agent 共享了一个 LLM 对象,或在多个 crew 间重复使用 | 每个 crew 中的每个 Agent 使用一个 LLM,或统计 LLMCallCompletedEvent |
Agent 在 akickoff() 下从不使用其 MCP 工具 | 运行中的事件循环内,mcps 中使用了 https:// 字符串 | 使用 MCPServerHTTP(url=...) |
Embedding function conflict ... persisted: openai | 知识是使用另一个嵌入器存储的 | crewai reset-memories -kn |
Collection expecting embedding with dimension of 1536, got 3072 | 知识是使用另一个 OpenAI 嵌入模型存储的 | crewai reset-memories -kn |
Crew 成功后,crewai run 报告 non-zero exit status 1 | run() 返回了 CrewOutput | 不要返回它 |
12. 检查清单
- 已检查
crewai version;如果不是 1.15.x,已重新核对各行 - 每个
Agent/Task/Crewkwarg 都存在于model_fields中 - 工具从
crewai.tools导入,flow 装饰器和persist从crewai.flow导入 - 每个任务都有
expected_output - 每个非 OpenAI 模型字符串都在
pyproject.toml中配置了对应的扩展 - 在 Python 中通过
output_pydantic设置了结构化输出,并断言out.pydantic非 None - Guardrail 返回
(bool, value),且注解为tuple[bool, Any]或不添加注解 - Memory 和知识都显式指定了嵌入器,或在环境中设置了提供商密钥
- 未使用
CodeInterpreterTool、allow_code_execution、ShortTermMemory、memory_config - 通过
crewai create crew <name> --classic创建 Classic 项目;通过uv add添加提供商扩展 - CI 和脚本使用 Classic crew(
crewai create crew <name> --classic),并通过uv run run_crew运行
参考资料
- 验证已安装的 API - 用单行命令检查已安装的 crewai 中的字段、默认值和签名;存储路径;用于记忆和知识的离线嵌入器
- 源代码凭据 - 每一行对应的 crewai 源文件和行号,方便你在升级后重新核查
- 公开文档:https://docs.crewai.com
相关技能:
- ask-docs - 当某一行内容可能已更改时,查询最新的 CrewAI 文档
- getting-started - 项目脚手架搭建,以及选择 crews 还是 flows
- design-agent / design-task - API 确认无误后,调整 Agent 和任务
- build-flow - Flow 状态、路由器、
@persist、人工反馈 - connect-tools-and-mcp -
BaseTool、@tool、mcps=[...] - test-crewai-project - 离线模拟 LLM 和确定性测试
- deploy-to-amp / call-deployed-crew - 发布和调用 crew