关于 deploy-to-amp
deploy-to-amp 是面向 Claude Code 的技能,用于将 CrewAI crew 和 flow 部署到 CrewAI AMP。它着重说明部署前验证、项目结构、上传行为和环境变量,帮助排查部署错误。
主要功能
- 01部署前验证检查
- 02Crew 和 flow 结构指南
- 03Git 与 ZIP 部署行为
- 04环境变量部署说明
- 05部署状态与日志排查
适用场景
- 01部署前检查 CrewAI 项目
- 02排查 AMP 构建失败
- 03确认推送包含的代码和环境变量
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ crewaiinc/ skills --skill deploy-to-amp安装后在 Claude Code 中输入/deploy-to-amp确认已加载。
附带文件references/validate-checks.mdreferences/what-gets-uploaded.md
详细介绍
部署到 CrewAI AMP
将 Crew 或 Flow 部署到 AMP,避免因项目结构错误、代码过时、环境变量值过时或组织不匹配而浪费部署次数。
已于 2026-10-01 根据 crewai 1.15.22 和 1.15.23 验证。
已于 2026-10-01 在 CrewAI AMP 和真实大模型上进行实测。
先运行 crewai version;如果主版本号或次版本号不同,请先使用 ask-docs 技能重新验证下方对版本敏感的条目,再依此操作。
1. 部署前检查 - 每次都运行以下三项
crewai org current # which org will receive this deploy (machine-wide, see section 5)
uv lock && git status # lockfile fresh, and you know what is uncommitted
crewai deploy validate # local checks, no platform contact, exit 1 on blocking errors
crewai deploy create 和 crewai deploy push 会自动运行相同的验证(只有在清楚原因时才使用 --skip-validate 跳过)。每个 crewai deploy 子命令(包括 status --uuid)都必须从项目根目录运行;在其他位置运行会停止并显示 Error: pyproject.toml not found.。
在脚本或 CI 中,退出码并不是可靠的信号。crewai deploy validate 遇到错误时会以 1 退出,但内置验证失败时,create 和 push 会以 0 退出(Pre-deploy validation failed. Fix the issues above or re-run with --skip-validate.);遇到 deployment_not_found 时,status / logs 也会以 0 退出。请在 CI 中以 crewai deploy validate 作为门禁,并检查命令输出,而不只是 $?。
Validate 会导入项目,这会创建 crewai 的本地存储目录(在 macOS 上为 ~/Library/Application Support/<pkg>/)。在 CI 或共享机器上运行时,请将 CREWAI_STORAGE_DIR 设置为临时路径。
2. 构建所需的项目结构
| 要求 | Crew(经典模式,crewai create crew <name> --classic) | Flow(crewai create flow <name>) |
|---|---|---|
| 部署名称 | [project].name,原样使用(脚手架会写入下划线:research_crew) | 相同 |
[tool.crewai] type | "crew" | "flow" |
| 锁文件 | 根目录中的 uv.lock(或 poetry.lock),并提交到版本库 | 相同 |
| 包目录 | src/<pkg>/,其中 <pkg> 是经过规范化的 [project].name(research-crew -> research_crew) | 相同 |
| 入口代码 | src/<pkg>/crew.py 中包含 @CrewBase 类,并包含 config/agents.yaml 和 config/tasks.yaml | src/<pkg>/main.py 中包含一个无需参数即可构建的 Flow 子类,并提供 kickoff() |
| 脚本(脚手架) | run_crew = "<pkg>.main:run" | kickoff = "<pkg>.main:kickoff" |
| 导入 | 绝对导入:from research_crew.tools.x import Y | 绝对导入:from acme_flow.crews.content_crew.content_crew import ContentCrew |
JSON 优先的 Crew(直接运行 crewai create crew <name>,不带 --classic)会将 crew.jsonc 和 agents/ 保留在项目根目录,而不是放在 src/ 下;crewai deploy validate 也会检查这种布局。
通过验证的最简 Flow main.py:
from crewai.flow import Flow, listen, start
from pydantic import BaseModel
class ReportState(BaseModel):
topic: str = "AI agents"
summary: str = ""
class ReportFlow(Flow[ReportState]):
@start()
def gather(self):
return f"notes on {self.state.topic}"
@listen(gather)
def summarize(self, notes):
self.state.summary = notes.upper()
return self.state.summary
def kickoff():
ReportFlow().kickoff()
if __name__ == "__main__":
kickoff()
结构规则及其可避免的故障
| 错误写法 | 结果 | 正确写法 |
|---|---|---|
在 crew.py / main.py 中使用 from .stub_tools import X | crewai run 可以正常运行,但 crewai deploy validate 会失败,并报错 Crew class annotated with @CrewBase not found(加载器会在包外运行该文件,并隐藏真正的 attempted relative import 错误)。使用 --skip-validate 推送后,AMP 构建也会以相同方式失败:ImportError: attempted relative import with no known parent package | from research_crew.stub_tools import X |
main.py 中只有 def kickoff():,没有 Flow 类 | No Flow subclass found in the module | 定义 class MyFlow(Flow[...]),并在 kickoff() 中调用它 |
Flow 的 __init__(self, tenant: str) | No Flow subclass found——该类必须能在无参数的情况下构建 | 通过 kickoff(inputs={...}) 将每次运行的值传入状态 |
在 crew 项目中设置 type = "flow" | No Flow subclass found | type = "crew" |
在 flow 项目中设置 type = "crew" | Cannot find src/<pkg>/crew.py、Cannot find src/<pkg>/config | type = "flow" |
将 src/research_crew/ 重命名为 src/researchcrew/ | Cannot find src/research_crew/ 和 Hatchling cannot determine which files to ship | 保持目录名与规范化后的 [project].name 一致 |
缺少 uv.lock | missing_lockfile 错误 | 运行 uv lock,然后执行 git add uv.lock |
锁定后编辑了 pyproject.toml | stale_lockfile 警告(不会阻止操作)——部署的依赖项可能与本地不同。检查会比较文件时间;如果缺少 [tool.crewai] project_id,CLI 本身也会将其写入 pyproject.toml,这同样会触发警告 | 每次编辑 pyproject.toml 后都重新运行 uv lock。如果锁文件已是最新版本,uv lock 不会改动它,因此警告可能仍会出现;如果 uv lock --check 通过,运行 touch uv.lock 可清除此警告,并一并提交这两个文件 |
通过 sys.path 从同级目录(../shared_lib)导入代码 | 本地验证通过,但上传的只有项目根目录:AMP 构建会失败,并报错 ModuleNotFoundError: No module named 'helpers',状态为 Automation error, fix the code and deploy again. | 将共享代码移入 src/<pkg>/,或将其发布为软件包依赖项 |
使用 anthropic/... 模型,却只安装普通的 crewai[tools] | 本地报错:Anthropic native provider not available, to install: uv add "crewai[anthropic]";验证时只报告 @CrewBase not found / No Flow subclass found,因此 create 和 push 会拒绝该项目 | 运行 uv add "crewai[anthropic]",使该额外依赖写入 pyproject.toml 和 uv.lock。 |
将数据文件放在 src/<pkg>/ 内,并将其作为包数据加载,不要使用基于仓库根目录构建的路径。src/<pkg>/ 下的文件会打入脚手架构建的 wheel;项目根目录下的文件则不会。
from importlib.resources import files
rules = files("research_crew").joinpath("data/rules.json").read_text()
当 validate 报告 @CrewBase not found 或 No Flow subclass found,但类明明存在时,说明加载器吞掉了真正的错误。请通过回溯信息复现该错误:
# 1. Run the file outside its package, as the loader does (catches relative imports and import-time errors)
uv run python -c "import runpy; runpy.run_path('src/research_crew/crew.py', run_name='deploy_check')" # flows: src/<pkg>/main.py
# 2. Build the object with no arguments (catches missing provider extras and Flow `__init__` arguments)
uv run python -c "from research_crew.crew import ResearchCrew; ResearchCrew().crew()"
uv run python -c "from acme_flow.main import ContentFlow; ContentFlow()"
所有检查项及代码请参阅 validate-checks.md。
3. 三种部署路径及各自上传的内容
| 路径 | AMP 构建的代码 | 发送的环境变量 |
|---|---|---|
crewai deploy create,项目有 origin 远程仓库 | AMP 克隆仓库;不会从本地磁盘上传任何内容。AMP 需要通过 AMP 组织中的连接获得仓库的读取权限(Settings > Git Repositories:GitHub OAuth 或 Any Git Repository)——否则,create 仍会显示 Deployment created successfully!,随后构建会因 git_clone_failure(could not read Username for 'https://github.com')而失败 | 本地 .env 中的所有键,发送前会提示“Press Enter to continue with N env vars: ...”(-y 可跳过提示) |
crewai deploy create,没有 origin 远程仓库 | 工作树的 ZIP 文件(会显示 No origin remote found. Deploying from a ZIP upload instead.) | 本地 .env 中的所有键,发送前会显示相同提示 |
crewai deploy push,本地存在 origin | 不会上传任何内容;AMP 会根据部署自身的源代码重新构建 | 无 |
crewai deploy push,本地没有 origin | 工作树的全新 ZIP 文件,包括未提交的编辑 | 本地 .env 中的所有键,不会提示——并且会替换部署的变量(见第 4 节) |
| 控制台,通过 Deploy from Code 部署(GitHub OAuth 或 Git Repository 标签页) | 从连接中选择的仓库和分支(可选:在有新提交时自动部署) | 你在控制台中输入的内容 |
| 控制台,上传 ZIP | 你选择的 ZIP 文件 | 你在控制台中输入的内容 |
push 会根据本地 origin 决定上传 ZIP 文件还是重新构建,而 AMP 会根据部署创建时使用的源代码进行构建。如果两者不一致,push 可能会成功,但不会发布你的更改:
| 部署创建方式 | push 时的本地状态 | 结果 |
|---|---|---|
| ZIP | 后来添加了 origin | 未上传 ZIP;AMP 使用最近一次上传的 ZIP 重新构建。工作树代码和 .env 更改均未部署,状态恢复为 Crew is Online |
| Git | 移除了 origin | CLI 上传了 ZIP 和 .env;AMP 忽略 ZIP,并再次克隆仓库 |
由此得出的规则:
- 在运行
create后,切勿为项目添加或移除origin。ZIP 部署成功推送时会显示Preparing project ZIP...和Uploading project ZIP...;如果缺少这些行,就没有任何新内容发布。 - 基于 Git:AMP 在远程服务上构建提交,而不是在你的磁盘上构建。未提交的编辑和未推送的本地提交都会被跳过(构建使用的是上次推送的版本,状态为
Crew is Online)。依次运行git commit、git push,然后运行crewai deploy push。 - 基于 ZIP:ZIP 包含 Git 跟踪的文件,以及未被忽略的未跟踪文件;并始终排除
.env、.env.*(.env.example/.env.sample除外)、.git、.venv、缓存、build/和dist/。将运行输出(report.md、output/)和临时文件加入.gitignore,否则它们也会被打包。运行时不要依赖根目录级别的点文件:.gitignore和.env.example在 ZIP 中,但不在已部署项目的根目录中。 - 如果目录尚无提交(脚手架会运行
git init,但不会提交),create/push会将所有未被忽略的内容提交为 "Initial crew"。如果缺少uv.lock,验证过程中的uv run会在上传前创建它(而create/push会改用crewai install)。 - 仅打包项目根目录。单体仓库的子文件夹需要在控制面板中设置工作目录(CLI 创建流程没有此选项)。
- 如果运行
push时未指定--uuid,它会根据所选组织中的[project].name查找部署。同一组织中的部署名称并不唯一,因此请保持名称稳定,并在脚本中优先使用--uuid。 push会打印部署的完整记录,包括公开 URL 和承载 token。不要将push输出粘贴到工单中,也不要将其保留在 CI 日志中。crewai deploy status只会打印名称和状态。crewai deploy logs会获取部署(构建)日志。部署失败时,请在那里查看实际错误(ModuleNotFoundError ...、git_clone_failure):状态行只会显示Automation error, fix the code and deploy again.、Provisioning Failed, try again.或Something went wrong, try again.。请从启动结果或控制面板的 Executions 和 Traces 标签页查看运行输出。Crew is Online表示构建已完成,且 AMP 的项目导入测试已通过。运行时问题(例如缺少提供商密钥、模型名称错误)只会在启动时出现——例如状态为FAILED,并显示ValueError: ANTHROPIC_API_KEY is required。每次部署后,都要用成本最低的实际输入启动一次并查看输出(参见call-deployed-crew)。
完整矩阵、排除项,以及用于列出 ZIP 部署内容的脚本:what-gets-uploaded.md。
4. 环境变量
环境变量属于各个部署。在 AMP 仪表板中,将提供商密钥(OPENAI_API_KEY、ANTHROPIC_API_KEY 等)和工具密钥(SERPER_API_KEY 等)设为相应部署的环境变量,并通过启动任务确认它们生效,而不要假定组织级设置会传递到你的代码中。
CLI 对本地 .env 的处理方式:
| 情况 | 发送内容 |
|---|---|
执行 create 时存在 .env | 所有非注释的 KEY=VALUE 行,不做筛选——包括文件中的无关密钥 |
执行 ZIP push 时存在 .env(没有本地 origin) | 同上,并且部署变量会被替换为这一组确切的变量:.env 中缺失的密钥会从部署中删除 |
不存在 .env | 完全不发送环境变量字段(会打印 Error: .env not found. 并继续);部署保留当前变量 |
执行带有本地 origin 的 push | 绝不发送环境变量——请在仪表板中更改变量值。基于 Git 的部署会保留 create 时的变量,直到你在那里编辑 |
变量值会原样发送:MAX_CASES=3 # note 会以 3 # note 的形式到达(python-dotenv 会在本地剥离注释并得到 3,因此本地运行时不会暴露这个问题),而 QUOTED="abc" 到达时仍带有引号。请在 .env 中使用不带引号的值,且不要添加行内注释。
若要推送代码但不修改 ZIP 部署的变量,请在不含 .env 的目录树中运行 crewai deploy push(将 .env 移到一边),并在仪表板中管理变量。绝不要使用不完整的 .env 进行推送。请附带一个包含 <your-key> 占位符的 .env.example,以记录所需的变量名。
部署时需要注意的提供商相关事项:
- 未设置
llm=的 Agent 会使用 OpenAI 默认模型(gpt-4.1-mini),因此即使项目只使用 Anthropic,也需要OPENAI_API_KEY。请为每个 Agent 设置llm=。 - 原生提供商会从
api_key=或相应的提供商变量中读取密钥;如果缺少密钥,会在启动任务时而非部署时失败:ValueError: OPENAI_API_KEY is required、ValueError: ANTHROPIC_API_KEY is required。 - 非 OpenAI 提供商属于额外依赖:
crewai[anthropic]、crewai[google-genai]、crewai[bedrock]、crewai[azure-ai-inference]。使用uv add添加它们,使其写入pyproject.toml和uv.lock;如果缺少额外依赖,验证(因此也包括create/push)会拒绝该项目。 - 当代码通过
os.getenv("SERPER_API_KEY")等方式读取已知密钥,而该密钥既不在.env中也不在 Shell 环境中时,crewai deploy validate会发出警告(env_vars_not_in_dotenv)。这只是提醒你将密钥添加到部署中,并非阻止项。
5. 组织选择是整台机器共用的
CLI 会在 ~/.config/crewai/settings.json 中为每个操作系统用户保留一个已选组织,并且每次平台调用(deploy create/push/status/logs/list/remove)都会携带该组织。在一个终端中切换组织,会影响这台机器上的所有 Shell 和项目。
- 每次执行
create、push或remove前运行crewai org current。(在 1.15.22-1.15.23 中,仅运行crewai org不会输出任何内容——请使用current子命令。) crewai org list会显示你所属的组织;crewai org switch <org-id>会更改当前选择。crewai login会将当前选择替换为平台报告的该账号当前组织,因此每次登录后都要用crewai org current再次确认。deployment_not_found(Request to Enterprise API failed. Details: deployment_not_found)表示所选组织中没有对应 UUID 或名称的部署。通常是因为 CLI 指向了不拥有该部署的其他组织,或者[project].name在create后发生了更改(按名称查找)。请先检查crewai org current,再检查名称或--uuid。- 驱动 CLI 的脚本和 CI 应在启动时显式切换组织并进行验证,绝不要依赖上次选择的组织。
6. 常见错误
| 症状 | 原因 | 修复方法 |
|---|---|---|
| 部署状态为 Online,但运行的是旧代码 | 基于 Git 的部署未推送更改;或者从现在已有 origin 的目录进行 ZIP 部署(并未上传 ZIP) | 执行 git push,然后执行 crewai deploy push;对于 ZIP,移除添加的 origin 后重新推送——检查是否出现 Uploading project ZIP... |
编辑 .env 后,部署仍保留旧环境变量值 | 使用本地 origin 推送时不会发送环境变量 | 在控制面板中编辑这些值 |
| 旧值覆盖了轮换后的密钥,部署中出现无关密钥,或某个密钥消失 | ZIP create/push 会上传本地 .env 中的全部密钥,并替换部署中的密钥集 | 从不含 .env 的目录部署,或确保其中包含该部署所需的完整密钥集 |
部署状态为 Online,但启动时显示 FAILED,并报错 ValueError: ANTHROPIC_API_KEY is required | 部署中缺少密钥(通常是使用不完整的 .env 推送 ZIP 时移除了密钥) | 在控制面板中设置密钥,或使用完整的 .env 推送 |
git_clone_failure,could not read Username for 'https://github.com' | 基于 Git 的部署,但 AMP 无权访问该(私有)仓库 | 检查 AMP 组织中的 Settings > Git Repositories:如果其中只提供“Configure GitHub”/“Add Repository”,说明尚未连接任何内容。连接 GitHub(或添加该仓库),并确保有权访问此仓库,然后重新推送:通过 CLI 创建的部署会在下次 push 时获取连接,无需在控制面板中操作,也无需重新创建部署。在此之前,每次 push 都会重新执行相同的克隆操作,并以相同方式失败。也可以从 ZIP 部署(项目没有 origin) |
Automation error, fix the code and deploy again. | AMP 构建的导入测试失败 | crewai deploy logs 会显示实际的回溯信息 |
MAX_CASES 被解析为 3 # note | .env 中的行内注释被原样发送 | 只使用纯值 |
Expected to find at least one of these files: uv.lock or poetry.lock | 缺少锁文件 | 执行 uv lock 并提交该文件 |
明明没有运行 uv lock,但第二次验证却通过了 | 验证时的导入检查运行了 uv run,因此创建了 uv.lock | 提交新生成的 uv.lock(基于 Git 的构建只能看到已提交的文件) |
存在装饰器,却出现 Crew class annotated with @CrewBase not found | 使用了相对导入、缺少 provider extra,或 crew.py 中存在任何导入错误 | 运行第 2 节中的诊断命令,查看实际错误 |
No Flow subclass found in the module | 没有 Flow 类、Flow 需要构造函数参数,或某个 crew 设置了 type = "flow" | 添加无参 Flow 子类;修正 type |
在本地可运行的代码在 AMP 上出现 ImportError | 导入了项目根目录之外的内容 | 将其移至 src/<pkg>/ 下,或将其作为依赖项 |
Anthropic native provider not available | pyproject.toml 中缺少 extra | 执行 uv add "crewai[anthropic]" |
启动时出现 ValueError: OPENAI_API_KEY is required | Agent 未设置 llm=,或使用了 OpenAI 模型但部署中没有密钥 | 明确设置 llm=;将密钥添加为部署环境变量 |
推送、查看状态或日志时出现 deployment_not_found | 选错了组织,或 [project].name 不再与部署名称匹配 | 执行 crewai org current,然后执行 crewai org switch <org-id>;或传入 --uuid |
运行任何 crewai deploy 子命令时出现 Error: pyproject.toml not found. | 当前目录不在项目目录中 | cd 到项目根目录 |
| 从 monorepo 子目录进行部署时无法找到项目 | 默认只使用仓库根目录或 ZIP 根目录 | 在控制面板中设置工作目录 |
7. 部署检查清单
-
crewai org current显示预期的组织 -
[tool.crewai] type与项目类型(crew 或 flow)相符 -
src/<pkg>/与[project].name相符;crew 包含@CrewBase+config/*.yaml,flow 包含一个无参Flow子类 +kickoff() - 所有项目导入都使用绝对路径;未从项目根目录之外导入任何内容
- 使用
uv add添加提供商额外依赖(crewai[anthropic]等);最后一次编辑pyproject.toml后运行uv lock - 已提交
uv.lock -
crewai deploy validate以状态码 0 退出 - 基于 Git 的部署:更改已提交并推送,且 AMP 可以访问仓库。基于 ZIP 的部署:创建后未添加
origin;运行输出和临时文件已忽略 -
.env中仅包含本次部署所需的完整密钥集,且值不带引号;或者已将其移到其他位置,确保不会发送任何内容 - 已在控制面板中将提供商和工具密钥设置为部署的环境变量
- 推送输出中显示了
Uploading project ZIP...(ZIP)——且没有将其粘贴到任何地方(其中包含 bearer token) - 状态变为 Online 后,进行了一次低成本的 kickoff,并返回预期输出
参考资料
- 上传内容 - 按路径划分的矩阵、ZIP 包含/排除规则、环境变量处理方式,以及用于列出 ZIP 部署所含内容的脚本
- 验证检查 -
crewai deploy validate的每项检查、对应代码和严重级别,以及其无法检测的问题 - 公开文档:部署准备、部署到 AMP、自动化、单体仓库部署、CLI
相关技能:
- call-deployed-crew - 部署状态变为 Online 后使用
/inputs、/kickoff、/status - test-crewai-project - 使用离线 stub LLM,无需密钥即可运行
crewai run和 validate - check-crewai-api - 当前的
LLM模型字符串、默认模型、结构化输出 - build-flow - Flow 状态、路由器、持久化
- connect-tools-and-mcp - 托管部署支持哪些工具和 MCP 传输方式
- ask-docs - 查询实时文档,了解此处未涵盖的内容