check-crewai-api

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Check CrewAI API

检查 CrewAI API

Load this before writing or reviewing crewai code: it maps what you probably remember to what crewai 1.15.x actually accepts.
Verified against crewai 1.15.22 and 1.15.23 on 2026-10-01. Live-tested with real LLMs on 2026-10-01. Run
crewai version
first; if the major/minor differs from 1.15, re-verify version-sensitive rows with the
ask-docs
skill before trusting them.

编写或审查 crewai 代码前先加载本文:它将你可能记得的内容映射到 crewai 1.15.x 实际接受的内容。
已针对 crewai 1.15.22 和 1.15.23 于 2026-10-01 进行验证。 已于 2026-10-01 使用真实 LLM 进行实测。 先运行
crewai version
;如果主版本或次版本与 1.15 不同,请先使用
ask-docs
skill 重新验证与版本相关的条目,再信任这些内容。

1. Three rules before you write anything

1. 开始编写前必须了解的三条规则

  1. Unknown keyword arguments are silently ignored.
    Agent
    ,
    Task
    and
    Crew
    accept and drop parameters that do not exist.
    Crew(memory_config={...})
    and
    Task(response_format=Model)
    construct fine and do nothing. A stale parameter name never raises, so check it exists:
    python
    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])
  2. The installed source wins over any doc, tutorial, or memory. That includes the
    AGENTS.md
    that
    crewai create
    writes into new projects. When a row below matters, check the installed signature (see verify-installed-api.md).
  3. Assert on structured output at the boundary. Several mistakes below fail quietly with
    out.pydantic is None
    while the run reports success.

  1. 未知的关键字参数会被静默忽略。
    Agent
    、
    Task
    和
    Crew
    会接受并丢弃不存在的参数。
    Crew(memory_config={...})
    和
    Task(response_format=Model)
    可以成功构造,但不会产生任何作用。过时的参数名不会引发异常,因此应检查该参数是否存在:
    python
    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])
  2. 已安装的源码优先于任何文档、教程或记忆。 这也包括
    crewai create
    写入新项目的
    AGENTS.md
    。当下表中的某一项很重要时,请检查已安装版本的函数签名(参见 verify-installed-api.md)。
  3. 在边界处断言结构化输出。 下文中的若干错误会在运行报告成功时静默失败,并出现
    out.pydantic is None
    。

2. Imports

2. 导入

You probably wroteCurrent 1.15.x formWhat the wrong form does
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
(the classes are gone)
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
No replacement in crewai - use a sandbox tool or service
ImportError
(removed)
The current top-level and project imports:
python
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

你可能这样写当前 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
(已移除)
当前顶层导入和项目导入方式:
python
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 parameters and defaults

3. Agent、Task、Crew 的参数和默认值

ParameterCurrent valueNote
Task.expected_output
required
Task(description=...)
alone raises
ValidationError ... expected_output Field required
Agent.max_iter
25
Do not assume 15 or 20
Agent.llm
None
-> resolved at construction
From env
MODEL
, then
MODEL_NAME
, then
OPENAI_MODEL_NAME
, else
gpt-4.1-mini
Agent.cache
True
Only permits caching; it does not turn it on
Crew.cache
False
Tool-result caching is opt-in: set
Crew(cache=True)
Crew.memory
False
Crew.process
Process.sequential
Only
sequential
and
hierarchical
exist
Task.guardrail_max_retries
3
max_retries
is deprecated (DeprecationWarning)
You probably wroteCurrent formWhat the wrong form does
Process.consensual
Process.sequential
or
Process.hierarchical
AttributeError
Crew(process=Process.hierarchical, ...)
with no manager
add
manager_llm="openai/gpt-4.1-mini"
or
manager_agent=...
ValidationError: Attribute manager_llm or manager_agent is required
Crew(memory=True, memory_config={...})
Crew(memory=Memory(...))
memory_config
is silently ignored
Agent(allow_code_execution=True)
/
code_execution_mode="unsafe"
Remove; use a sandbox toolDeprecated no-ops;
allow_code_execution=True
emits a
DeprecationWarning
Crew(function_calling_llm=...)
Remove, or set
llm
per agent
Deprecated,
DeprecationWarning
Two
async_execution=True
tasks with the same
agent
One agent per concurrent async task
RuntimeError: Executor is already running. Cannot invoke the same executor instance concurrently.
python
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)

参数当前值说明
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
添加
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
的 task 使用同一个
agent
每个并发异步 task 使用一个独立的 agent
RuntimeError: Executor is already running. Cannot invoke the same executor instance concurrently.
python
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. Running a crew and reading the result

4. 运行 Crew 并读取结果

You probably wroteCurrent formWhat the wrong form does
crew.kickoff("honey bees")
crew.kickoff(inputs={"topic": "honey bees"})
TypeError: inputs must be a dict or Mapping, got str
await crew.kickoff_async(...)
for native async
await crew.akickoff(...)
Works, but
kickoff_async
runs the sync
kickoff
in a thread (
asyncio.to_thread
)
result.output
/
result.final_output
/
result.result
result.raw
AttributeError: 'CrewOutput' object has no attribute ...
crew.kickoff(...)
then
crew.kickoff_for_each(...)
on the same
Crew
Build a fresh
Crew
for
kickoff_for_each
(or call it before any
kickoff
)
No error, but every run reuses the first kickoff's inputs: the per-run copies keep the already-interpolated task text
Agent(mcps=["https://..."])
in a crew run with
await crew.akickoff()
mcps=[MCPServerHTTP(url="https://...")]
(from
crewai.mcp
)
No error, but the agent gets zero MCP tools: string refs resolve with
asyncio.run()
, which fails inside a running event loop (see connect-tools-and-mcp)
CrewOutput
fields:
raw
,
pydantic
,
json_dict
,
tasks_output
(a list of
TaskOutput
),
token_usage
.
out["field"]
reads from
pydantic
/
json_dict
.
kickoff_for_each(inputs=[...])
returns a list of
CrewOutput
.
token_usage
is summed over each agent's
LLM
object for that object's whole lifetime, not per run. One
LLM(...)
instance shared by two agents counts every call twice, and one reused across crews carries the earlier crews' tokens (verified with
anthropic/claude-haiku-4-5
: a second one-call crew on the same
LLM
reported 148 tokens and 2 requests, a fresh
LLM
73 and 1). For per-run cost, give each crew its own
LLM
objects, or count
LLMCallCompletedEvent
s (
event.usage
).
python
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)

你可能这样写当前形式错误形式的表现
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 的 inputs:每次运行生成的副本仍保留已经插值过的 task 文本
在通过
await crew.akickoff()
运行 Crew 时使用
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
对象整个生命周期汇总的,并非按单次运行计算。同一个
LLM(...)
实例被两个 agent 共享时,每次调用都会被计算两次;跨 Crew 复用该实例时,还会携带之前 Crew 的 token(已使用
anthropic/claude-haiku-4-5
验证:复用同一个
LLM
的第二个单次调用 Crew 报告了 148 个 token 和 2 次请求,而使用新的
LLM
时为 73 个 token 和 1 次请求)。如需计算单次运行的成本,请为每个 Crew 配置独立的
LLM
对象,或统计
LLMCallCompletedEvent
(
event.usage
)。
python
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. LLMs, model strings, and provider extras

5. LLM、模型字符串和提供商附加包

LiteLLM is no longer a dependency.
LLM(model=...)
is a factory that returns a native provider class; only the OpenAI SDK ships with core crewai.
You probably wroteCurrent formWhat the wrong form does
llm="anthropic/claude-sonnet-4-5"
with plain
crewai
installed
uv add "crewai[anthropic]"
, then the same string
ImportError: Anthropic native provider not available, to install: uv add "crewai[anthropic]"
llm="gemini/gemini-2.5-flash"
with plain
crewai
uv add "crewai[google-genai]"
ImportError: Google Gen AI native provider not available
llm="groq/llama-3.3-70b-versatile"
(or
mistral/...
, any non-native provider)
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.
No
llm=
and assuming
gpt-4
Default is
gpt-4.1-mini
; set
MODEL=...
or
llm=
llm.call(messages, response_format=Model)
llm.call(messages, response_model=Model)
TypeError: ... unexpected keyword argument 'response_format'. Did you mean 'response_model'?
Custom
BaseLLM.call(self, messages, tools=None, callbacks=None, available_functions=None)
Also accept
from_task=None, from_agent=None, response_model=None
(or
**kwargs
)
TypeError: call() got an unexpected keyword argument 'from_task'
at kickoff
Native providers: openai, anthropic/claude, azure, google/gemini, bedrock/aws, openrouter, deepseek, ollama, hosted_vllm, cerebras, dashscope, snowflake. Extras:
crewai[anthropic]
,
crewai[google-genai]
,
crewai[bedrock]
,
crewai[azure-ai-inference]
,
crewai[litellm]
. Construction never checks the key; kickoff does (
ValueError: OPENAI_API_KEY is required
, or
ANTHROPIC_API_KEY is required
; a wrong key gets the provider's
AuthenticationError ... 401
). The
crewai create
scaffolds never add a provider extra, even with
--provider anthropic/...
: run
uv add "crewai[anthropic]"
yourself.
python
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__)
A custom LLM subclasses
BaseLLM
and implements
call
with the full signature. If
call
forwards
messages
to a provider SDK, send only each message's
role
and
content
: crewai adds a
cache_breakpoint: True
key to some messages, and the Anthropic API rejects it with
400 ... messages.0.cache_breakpoint: Extra inputs are not permitted
.
python
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)

LiteLLM 不再是依赖项。
LLM(model=...)
是一个工厂,会返回原生提供商类;crewai 核心版本仅内置 OpenAI SDK。
你可能这样写当前形式错误形式的表现
仅安装普通
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
)
kickoff 时出现
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]
。构造对象时不会检查 API key;kickoff 时才会检查(
ValueError: OPENAI_API_KEY is required
或
ANTHROPIC_API_KEY is required
;错误的 key 会触发提供商的
AuthenticationError ... 401
)。即使使用
--provider anthropic/...
,
crewai create
生成的脚手架也不会添加提供商附加包;请自行执行
uv add "crewai[anthropic]"
。
python
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
。
python
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. Structured output

6. 结构化输出

WhereUseResult lands in
Task(output_pydantic=Model)
Parsed model on the task and crew output
out.pydantic
,
out["field"]
Task(output_json=Model)
Dict output
out.json_dict
Task(response_model=Model)
Native provider structured output only
out.raw
(JSON text);
out.pydantic
stays
None
Agent.kickoff(messages, response_format=Model)
Standalone agent
LiteAgentOutput.pydantic
llm.call(messages, response_model=Model)
Direct LLM callthe parsed model
LLM(model=..., response_format=Model)
Constructor-level default
You probably wroteCurrent formWhat the wrong form does
Task(response_format=Model)
Task(output_pydantic=Model)
Silently ignored
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)
Pick one
ValidationError: Only one output type can be set
Task(output_pydantic=M, output_file="report.md")
expecting prose in the file
Drop
output_pydantic
, or render the model yourself
The file gets the model's JSON, whatever the extension
output_file="/abs/path/report.md"
A relative path (or
output_file="{out_dir}/report.md"
via inputs)
The leading
/
is stripped, so the file lands under the current directory
output_pydantic: Report
in
tasks.yaml
Set
output_pydantic=Report
in the
@task
method in Python
With no matching
@output_pydantic
class:
KeyError: 'Report'
. With one: silently dropped,
out.pydantic is None
python
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)
In a
@CrewBase
project keep the model in Python even when the rest of the task is YAML:
python
@task
def research_task(self) -> Task:
    return Task(config=self.tasks_config["research_task"], output_pydantic=Report)

使用位置用途结果存放位置
Task(output_pydantic=Model)
解析后的模型,存在于 task 和 Crew 输出中
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解析后的模型
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"
使用相对路径(或通过 inputs 使用
output_file="{out_dir}/report.md"
)
前导
/
会被移除,因此文件会写入当前目录
在
tasks.yaml
中使用
output_pydantic: Report
在 Python 的
@task
方法中设置
output_pydantic=Report
没有匹配的
@output_pydantic
类时:
KeyError: 'Report'
。存在一个匹配类时:参数会被静默丢弃,
out.pydantic
为
None
python
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
项目中,即使 task 的其余内容使用 YAML,也应将模型保留在 Python 中:
python
@task
def research_task(self) -> Task:
    return Task(config=self.tasks_config["research_task"], output_pydantic=Report)

7. Guardrails

7. Guardrails

A function guardrail takes one argument (
TaskOutput
) and returns a tuple
(bool, value)
. On
False
the value is fed back to the agent as the error and the task retries, up to
guardrail_max_retries
(default 3); then the task raises
Task failed guardrail validation after N retries
. A string guardrail is checked by an extra LLM call.
You probably wroteCurrent formWhat the wrong form does
def g(out) -> bool: return True
def g(out: TaskOutput) -> tuple[bool, Any]
returning
(True, out.raw)
Annotated:
ValidationError: If return type is annotated, it must be Tuple[bool, Any]
at
Task(...)
. Unannotated:
TypeError: cannot unpack non-iterable bool object
at kickoff
-> tuple[bool, object]
-> tuple[bool, Any]
(or
str
,
TaskOutput
)
Same
ValidationError
at
Task(...)
Task(max_retries=2)
Task(guardrail_max_retries=2)
DeprecationWarning
Relying on
HallucinationGuardrail
Write a function guardrailIn open-source crewai it is a no-op that always passes
python
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=[...]
runs each guardrail in order; a successful string result replaces
out.raw
for the next one.

函数 guardrail 接收一个参数(
TaskOutput
),并返回元组
(bool, value)
。当结果为
False
时,value 会作为错误反馈给 agent,task 最多重试
guardrail_max_retries
次(默认 3 次);之后 task 会抛出
Task failed guardrail validation after N retries
。字符串 guardrail 需要额外调用一次 LLM 进行检查。
你可能这样写当前形式错误形式的表现
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
编写函数 guardrail在开源版 crewai 中,它是一个始终通过的空操作
python
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=[...]
会按顺序运行每个 guardrail;成功的字符串结果会替换
out.raw
,并传递给下一个 guardrail。

8. Memory and knowledge

8. Memory 和 Knowledge

Memory is one
Memory
class (LanceDB storage). Its defaults call OpenAI:
text-embedding-3-large
for embeddings and
gpt-5.4-mini
for analysis.
Crew(memory=True)
analyses with the first agent's
llm
instead, and knowledge with no
embedder
embeds with
text-embedding-3-small
. Live with an OpenAI key: a
memory=True
crew stored a codename in one process and a new crew recalled it in the next; crew and agent knowledge both answered from the source.
You probably wroteCurrent formWhat the wrong form does
ShortTermMemory()
,
LongTermMemory()
,
EntityMemory()
Memory(...)
ImportError
Crew(memory=True)
with no (or an invalid)
OPENAI_API_KEY
Set the key, or pass
Memory(llm=..., embedder=...)
Crew completes; every save fails silently (only a
MemorySaveFailedEvent
is emitted) and nothing is stored
memory.remember(...)
with no key
Same
RuntimeError: Memory requires an embedder for vector search
(an invalid key:
AuthenticationError ... 401
)
Agent(knowledge_sources=[...])
with no key or embedder, agent in a crew
Pass
embedder={...}
on the Agent or Crew
ValueError: Invalid Knowledge Configuration: The OPENAI_API_KEY environment variable is not set.
at crew kickoff (an invalid key:
AuthenticationError ... 401
)
agent.kickoff(...)
on an agent with
knowledge_sources
Run the agent as a task in a
Crew
, or put the facts in the prompt
No error with or without a key:
Agent.kickoff()
never queries agent knowledge, so the answer ignores it
Crew(knowledge_sources=[...])
with no key or embedder
SameLogs
Failed to upsert documents
; crew runs with no knowledge
Changing the knowledge
embedder
after a run stored knowledge
crewai reset-memories -kn
(or
crew.reset_memories(command_type="knowledge")
), then run
Embedding function conflict: new: <x> vs persisted: openai
; the crew runs with no knowledge
Adding
embedder={"provider": "openai"}
after knowledge was stored with no
embedder
(or changing the OpenAI embedding model)
Same reset
Failed to upsert documents: Collection expecting embedding with dimension of 1536, got 3072
(the explicit provider defaults to
text-embedding-3-large
); the crew answers without its knowledge
The embedder config shape is
{"provider": <name>, "config": {...}}
; the OpenAI model key is
model_name
.
"model"
raises
TypeError: ... unexpected keyword argument 'model'
in
Memory
, and for knowledge it is silently ignored (the crew embeds with
text-embedding-3-large
). The
ollama
provider below also needs
uv add ollama
and a running Ollama server with the model pulled; without the package, crew knowledge is silently
None
.
{"provider": "onnx"}
is a local, key-free embedder that core crewai can already run (chromadb's
onnxruntime
; about 80 MB of model downloaded on first use) - the design-agent skill's memory-and-knowledge reference has working examples. For a deterministic embedder in tests, use a callable (
Memory
) or a custom class (knowledge) - see verify-installed-api.md.
python
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?")
Reset stored data from the project directory with
crewai reset-memories -m
(memory; errors with
Memory memory system is not initialized
if the crew has no memory),
-kn
(knowledge),
-akn
(agent knowledge),
-k
(latest kickoff outputs),
-a
(all). The old
-s
,
-l
,
-e
flags are hidden deprecated aliases that print a warning and reset the unified memory. Storage path and offline embedders: verify-installed-api.md.

Memory 已统一为单个
Memory
类(使用 LanceDB 存储)。其默认配置会调用 OpenAI:embeddings 使用
text-embedding-3-large
,分析使用
gpt-5.4-mini
。
Crew(memory=True)
会改用第一个 agent 的
llm
进行分析;knowledge 未指定
embedder
时,会使用
text-embedding-3-small
生成 embeddings。使用有效的 OpenAI key 实测:一个
memory=True
Crew 在一个进程中存储了代号,新建的 Crew 在下一个进程中成功回忆了该代号;Crew 和 agent 的 knowledge 均能根据来源回答问题。
你可能这样写当前形式错误形式的表现
ShortTermMemory()
、
LongTermMemory()
、
EntityMemory()
Memory(...)
ImportError
使用
Crew(memory=True)
,但未设置有效或可用的
OPENAI_API_KEY
设置 key,或传入
Memory(llm=..., embedder=...)
Crew 会完成;每次保存都会静默失败(仅发出
MemorySaveFailedEvent
),且不会存储任何内容
调用
memory.remember(...)
时未设置 key
同上
RuntimeError: Memory requires an embedder for vector search
(key 无效时:
AuthenticationError ... 401
)
agent 位于 Crew 中,且
Agent(knowledge_sources=[...])
未设置 key 或 embedder
在 Agent 或 Crew 上传入
embedder={...}
Crew kickoff 时出现
ValueError: Invalid Knowledge Configuration: The OPENAI_API_KEY environment variable is not set.
(key 无效时:
AuthenticationError ... 401
)
对包含
knowledge_sources
的 agent 调用
agent.kickoff(...)
将该 agent 作为 task 放入
Crew
中运行,或将相关事实直接写入 prompt
无论是否设置 key 都不会报错:
Agent.kickoff()
永远不会查询 agent knowledge,因此回答会忽略这些内容
Crew(knowledge_sources=[...])
未设置 key 或 embedder
同上日志显示
Failed to upsert documents
;Crew 运行时没有 knowledge
运行并存储 knowledge 后更改 knowledge 的
embedder
执行
crewai reset-memories -kn
(或
crew.reset_memories(command_type="knowledge")
),然后再运行
Embedding function conflict: new: <x> vs persisted: openai
;Crew 运行时没有 knowledge
使用无
embedder
的配置存储 knowledge 后,再添加
embedder={"provider": "openai"}
(或更改 OpenAI embedding 模型)
执行相同的重置操作
Failed to upsert documents: Collection expecting embedding with dimension of 1536, got 3072
(显式提供商默认使用
text-embedding-3-large
);Crew 的回答不会包含 knowledge
Embedder 配置结构为
{"provider": <name>, "config": {...}}
;OpenAI 的模型键为
model_name
。在
Memory
中使用
"model"
会引发
TypeError: ... unexpected keyword argument 'model'
,而在 knowledge 中使用则会被静默忽略(Crew 会使用
text-embedding-3-large
生成 embeddings)。下面的
ollama
提供商还需要执行
uv add ollama
,并确保 Ollama 服务正在运行且已拉取所需模型;如果未安装该包,Crew 的 knowledge 会静默变成
None
。
{"provider": "onnx"}
是一种本地、无需 key 的 embedder,crewai 核心版本已经可以运行(使用 chromadb 的
onnxruntime
;首次使用时会下载约 80 MB 的模型)——design-agent skill 的 memory-and-knowledge 参考文档中提供了可用示例。如需在测试中使用确定性 embedder,请为 Memory 传入 callable,或为 knowledge 传入自定义类——参见 verify-installed-api.md。
python
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
(memory;如果 Crew 没有 memory,会报错
Memory memory system is not initialized
)、
-kn
(knowledge)、
-akn
(agent knowledge)、
-k
(最近一次 kickoff 的输出)、
-a
(全部)。旧的
-s
、
-l
、
-e
标志是隐藏的弃用别名;使用时会显示警告,并重置统一的 memory。存储路径和离线 embedder 参见 verify-installed-api.md。

9. Project scaffold and CLI

9. 项目脚手架和 CLI

You probably wroteCurrent formWhat the wrong form does
crewai create crew my_crew
expecting
crew.py
+ YAML
crewai create crew my_crew --classic
Starts an interactive wizard that writes a JSON project (
crew.jsonc
,
agents/*.jsonc
); with no TTY it prints
Aborted!
. Scripts that only need a crew should use
--classic --skip-provider
.
crewai run
on a JSON crew in CI or a script
For CI, create the crew with
crewai create crew <name> --classic
and run it with
uv run run_crew
Opens a full-screen run view that waits for the user to quit, even with no TTY, so the command never exits. An environment variable,
CREWAI_DMN=1
, skipped the run view on crewai 1.15.x, but it is unsupported and undocumented; may change
Leaving
"memory": true
from the JSON scaffold with no
OPENAI_API_KEY
Set the key, set
"memory": false
, or configure an embedder
The crew completes; memory recall and saves fail silently
crewai run --inputs '{...}'
on a classic crew
Put inputs in
main.py
run()
Error: --inputs is only supported for declarative flows and crews
crewai reset-memories -s -l -e
crewai reset-memories -m
Deprecated aliases, warning printed
return crew.kickoff(...)
from
main.run()
Do not return the outputThe
run_crew
script calls
sys.exit(<CrewOutput>)
and exits 1 after a successful run;
crewai run
prints
An error occurred while running the crew: ... non-zero exit status 1
Trusting
crewai run
's exit code in CI on a classic crew (
--classic
) or a Python flow
Run
uv run run_crew
(exit code propagates) or check the output
There
crewai run
exits 0 even when the crew or flow process failed; JSON (wizard) crews have no
run_crew
script, so create CI crews with
--classic
bash
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
The classic layout:
src/<name>/crew.py
(
@CrewBase
class),
src/<name>/config/agents.yaml
and
tasks.yaml
(keys match the
@agent
/
@task
method names),
main.py
, and
pyproject.toml
with
[tool.crewai] type = "crew"
and dependency
crewai[tools]
. In YAML,
llm: <name>
resolves to an
@llm
method of that name, otherwise it is used as a model string.
crewai create flow
also writes a
.env
with a placeholder
OPENAI_API_KEY
- replace it, never commit it.

你可能这样写当前形式错误形式的表现
执行
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 中可以跳过运行视图,但该方式不受支持且没有文档说明,未来可能发生变化
保留 JSON 脚手架中的
"memory": true
,但未设置
OPENAI_API_KEY
设置 key、将
"memory"
设为
false
,或配置 embedder
Crew 会完成;memory 的回忆和保存都会静默失败
对经典 Crew 执行
crewai run --inputs '{...}'
将 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()
中执行
return crew.kickoff(...)
不要返回输出
run_crew
脚本会调用
sys.exit(<CrewOutput>)
,即使运行成功也会以状态码 1 退出;
crewai run
会输出
An error occurred while running the crew: ... non-zero exit status 1
在 CI 中信任经典 Crew(
--classic
)或 Python flow 的
crewai run
退出码
运行
uv run run_crew
(退出码会正确传递),或检查输出
即使 Crew 或 flow 进程失败,
crewai run
也会退出 0;JSON 向导生成的 Crew 没有
run_crew
脚本,因此 CI Crew 应使用
--classic
创建
bash
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
经典项目布局:
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. Removed and deprecated

10. 已移除和已弃用的功能

FeatureStatus in 1.15.22-1.15.23Do instead
CodeInterpreterTool
Removed from
crewai_tools
Sandbox tool or service
Agent(allow_code_execution=...)
,
code_execution_mode
Deprecated no-opsSame
ShortTermMemory
,
LongTermMemory
,
EntityMemory
,
memory_config
Removed / ignored
Memory(...)
crewai.utilities.events
Removed
crewai.events
Crew(function_calling_llm=...)
DeprecatedPer-agent
llm
Task(max_retries=...)
Deprecated
guardrail_max_retries
crewai.cli
module
Deprecation shim
crewai_cli
(the CLI is its own package)
LiteLLM as a core dependencyOptional extra
crewai[litellm]
only for non-native providers

功能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. Common mistakes

11. 常见错误

SymptomCauseFix
A parameter has no effect and no errorUnknown kwargs are dropped by Agent/Task/CrewCheck
"name" in Task.model_fields
out.pydantic is None
output_pydantic
set in YAML, or
response_model
used instead of
output_pydantic
Set
output_pydantic=Model
in Python; assert non-None
ImportError: ... native provider not available
Provider SDK extra missing
uv add "crewai[anthropic]"
(or
[google-genai]
,
[bedrock]
,
[litellm]
)
ValueError: OPENAI_API_KEY is required
at kickoff
No
llm=
set, so the default
gpt-4.1-mini
was used
Set
llm=
or
MODEL
, plus the provider key
Crew finishes but nothing was remembered
memory=True
with no embedder key
Pass
Memory(embedder=...)
or set the key; listen for
MemorySaveFailedEvent
from
crewai.events
Knowledge never appears in promptsCrew-level knowledge failed to embedSet
embedder=
; look for
Failed to upsert documents
TypeError: ... unexpected keyword argument 'from_task'
Custom
BaseLLM.call
with the old signature
Accept
from_task
,
from_agent
,
response_model
,
**kwargs
Tuple[bool, Any]
ValidationError at
Task(...)
Guardrail annotated
-> bool
or
tuple[bool, object]
Annotate
-> tuple[bool, Any]
and return a tuple
crewai create crew
hangs or prints
Aborted!
It is an interactive JSON wizard nowAdd
--classic
for the
@CrewBase
layout; use it for CI and scripts
crewai run
never returns on a JSON crew
The run view waits for a keypressFor CI, use
crewai create crew <name> --classic
plus
uv run run_crew
kickoff_for_each
results all answer the first topic
The
Crew
was already kicked off
Build a fresh
Crew
per batch
token_usage
larger than the run could have used
An
LLM
object shared by several agents or reused across crews
One
LLM
per agent per crew, or count
LLMCallCompletedEvent
s
Agent never uses its MCP tools under
akickoff()
https://
string in
mcps
inside a running event loop
MCPServerHTTP(url=...)
Embedding function conflict ... persisted: openai
Knowledge was stored with another embedder
crewai reset-memories -kn
Collection expecting embedding with dimension of 1536, got 3072
Knowledge was stored with another OpenAI embedding model
crewai reset-memories -kn
crewai run
reports
non-zero exit status 1
after the crew succeeds
run()
returns the
CrewOutput
Do not return it

症状原因修复方法
参数没有任何作用,也没有报错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]
)
kickoff 时出现
ValueError: OPENAI_API_KEY is required
未设置
llm=
,因此使用了默认的
gpt-4.1-mini
设置
llm=
或
MODEL
,并配置提供商 key
Crew 完成运行,但没有记住任何内容
memory=True
,但没有 embedder key
传入
Memory(embedder=...)
或设置 key;监听来自
crewai.events
的
MemorySaveFailedEvent
Knowledge 从未出现在 prompt 中Crew 级 knowledge 的 embedding 失败设置
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
的结果全部回答第一个 topic
该
Crew
已经执行过 kickoff
每批任务构建一个新的
Crew
token_usage
大于本次运行可能产生的用量
多个 agent 共享同一个
LLM
对象,或该对象被多个 Crew 复用
每个 Crew 中的每个 agent 使用独立的
LLM
,或统计
LLMCallCompletedEvent
Agent 在
akickoff()
下从不使用 MCP 工具
在运行中的事件循环内为
mcps
传递了
https://
字符串
使用
MCPServerHTTP(url=...)
Embedding function conflict ... persisted: openai
Knowledge 使用了另一个 embedder 存储执行
crewai reset-memories -kn
Collection expecting embedding with dimension of 1536, got 3072
Knowledge 使用了另一个 OpenAI embedding 模型存储执行
crewai reset-memories -kn
Crew 成功后,
crewai run
仍报告
non-zero exit status 1
run()
返回了
CrewOutput
不要返回它

12. Checklist

12. 检查清单

  • crewai version
    checked; rows re-verified if not 1.15.x
  • Every
    Agent
    /
    Task
    /
    Crew
    kwarg exists in
    model_fields
  • Tools import from
    crewai.tools
    , flow decorators and
    persist
    from
    crewai.flow
  • Every task has
    expected_output
  • Every non-OpenAI model string has its extra in
    pyproject.toml
  • Structured output set in Python with
    output_pydantic
    , and
    out.pydantic
    asserted non-None
  • Guardrails return
    (bool, value)
    and are annotated
    tuple[bool, Any]
    or not at all
  • Memory and knowledge have an explicit embedder or a provider key in the environment
  • No
    CodeInterpreterTool
    ,
    allow_code_execution
    ,
    ShortTermMemory
    ,
    memory_config
  • Classic projects created with
    crewai create crew <name> --classic
    ; provider extra added with
    uv add
  • CI and scripts use classic crews (
    crewai create crew <name> --classic
    ) run with
    uv run run_crew

  • 已检查
    crewai version
    ;如果不是 1.15.x,已重新验证相关条目
  • 每个
    Agent
    /
    Task
    /
    Crew
    kwargs 都存在于
    model_fields
    中
  • Tool 从
    crewai.tools
    导入,flow 装饰器和
    persist
    从
    crewai.flow
    导入
  • 每个 task 都有
    expected_output
  • 每个非 OpenAI 模型字符串都在
    pyproject.toml
    中配置了对应的附加包
  • 在 Python 中使用
    output_pydantic
    设置结构化输出,并断言
    out.pydantic
    不为
    None
  • Guardrail 返回
    (bool, value)
    ,并使用
    tuple[bool, Any]
    注解或完全不使用注解
  • Memory 和 knowledge 都有显式 embedder,或环境中提供了提供商 key
  • 不使用
    CodeInterpreterTool
    、
    allow_code_execution
    、
    ShortTermMemory
    或
    memory_config
  • 经典项目通过
    crewai create crew <name> --classic
    创建;提供商附加包通过
    uv add
    添加
  • CI 和脚本使用经典 Crew(
    crewai create crew <name> --classic
    ),并通过
    uv run run_crew
    运行

References

参考资料

  • Verify the installed API - one-liners to check fields, defaults and signatures in the installed crewai; storage paths; an offline embedder for memory and knowledge
  • Source receipts - the crewai source file and line behind each row, so you can re-check after an upgrade
  • Public docs: https://docs.crewai.com
For related skills:
  • ask-docs - query the live CrewAI docs when a row may have changed
  • getting-started - project scaffolding and choosing crews vs flows
  • design-agent / design-task - tuning agents and tasks once the API is right
  • build-flow - Flow state, routers,
    @persist
    , human feedback
  • connect-tools-and-mcp -
    BaseTool
    ,
    @tool
    ,
    mcps=[...]
  • test-crewai-project - offline stub LLM and deterministic tests
  • deploy-to-amp / call-deployed-crew - shipping and calling a crew
  • 验证已安装的 API——用于快速检查已安装 crewai 中的字段、默认值和函数签名;还包含存储路径以及用于 memory 和 knowledge 的离线 embedder
  • 来源凭据——提供每个条目背后的 crewai 源文件和对应行,便于升级后重新核对
  • 公共文档:https://docs.crewai.com
相关 skills:
  • ask-docs——当某个条目可能已经发生变化时,查询最新的 CrewAI 文档
  • getting-started——项目脚手架以及在 Crew 与 flow 之间进行选择
  • design-agent / design-task——API 配置正确后,对 agent 和 task 进行调优
  • build-flow——Flow 状态、router、
    @persist
    和人工反馈
  • connect-tools-and-mcp——
    BaseTool
    、
    @tool
    、
    mcps=[...]
  • test-crewai-project——离线 stub LLM 和确定性测试
  • deploy-to-amp /
    call-deployed-crew
    ——部署和调用 Crew