DeerFlow 环境配置实战:config.yaml 定位、运行时路径与沙箱镜像预热
DeerFlow 是一个面向长周期任务的开源 SuperAgent 框架,其所有运行时行为(模型、工具、沙箱、技能路径)都由一份位于项目根目录的 config.yaml 驱动。本文基于仓库中的 SETUP.md 展开,完整覆盖配置创建、API Key 注入、配置定位规则、运行时路径环境变量与沙箱镜像预拉取等操作步骤,并结合 AppConfig、runtime_paths.py 等源码实现,说明每个环节在 DeerFlow 内部到底如何解析、何时会热重载、升级失败时如何诊断。
一、配置初始化:从示例文件到本地 config.yaml
DeerFlow 使用一份 YAML 配置文件,必须放在项目根目录(即 deer-flow/ 目录)下。官方示例配置为 config.example.yaml,完整初始化步骤如下:
- 进入项目根目录:
cd /path/to/deer-flow
- 复制示例配置:
cp config.example.yaml config.yaml
- 编辑配置,注入模型 API Key(两种任选其一):
# Option A: 设置环境变量(推荐)
export OPENAI_API_KEY="your-key-here"
# 可选:从其他目录运行 DeerFlow 时,显式固定项目根目录
export DEER_FLOW_PROJECT_ROOT="/path/to/deer-flow"
# Option B: 直接编辑 config.yaml
vim config.yaml # 或使用你习惯的编辑器
- 验证配置是否被正确加载:
cd backend
python -c "from deerflow.config import get_app_config; print('✓ Config loaded:', get_app_config().models[0].name)"
该验证命令打印 models 列表第一个模型的 name 字段,能一次性确认“配置文件找到了 → YAML 解析成功 → 模型列表非空”三件事。
环境变量引用语法
config.example.yaml 头部注释明确说明:所有字段值都支持环境变量引用,例如 api_key: $OPENAI_API_KEY。这一点在源码中有对应实现——app_config.py 中的 resolve_env_variables 会递归遍历整棵配置树:
- 字符串以
$开头时,通过os.getenv解析变量名; - 如果引用了未设置的环境变量,加载会直接抛出
ValueError(Environment variable XXX not found for config value ...),而不是静默置空——这是有意的 fail-fast 设计,能帮你尽早发现漏配。
因此推荐做法是:配置文件中写 api_key: $OPENAI_API_KEY 这类引用,密钥只存在于环境变量中。这与仓库的安全约定一致:config.yaml 已被 .gitignore 自动忽略(其中同时忽略 config.yaml 与升级备份 config.yaml.bak),避免含密文件被提交。
直接复制示例文件为何不会报错
config.example.yaml 中 models:、memory: 等大量顶层区块默认是“键存在但下面全是注释”的状态,PyYAML 会把它们解析成 None。如果框架直接把这些 None 交给 Pydantic,首跑流程会崩在不明的 Input should be a valid list 错误上。AppConfig 通过 _drop_null_config_sections 校验器把所有“存在但为 null”的区块丢弃、回退到各字段的默认值(列表区块变为空列表,对象区块使用默认配置),从而保证 cp config.example.yaml config.yaml 之后立刻可运行。唯一例外是 sandbox 这类无默认值、必须显式声明的区块——它在为 null 时仍会报错。
二、关键运行时路径:环境变量速查
SETUP.md 的 Important Notes 部分列出了四个必须理解的约定,其底层实现集中在 runtime_paths.py:
| 约定 | 默认值 | 控制变量 | 源码依据 |
|---|---|---|---|
| 配置文件位置 | 项目根目录 deer-flow/config.yaml |
DEER_FLOW_CONFIG_PATH(直接指定文件) |
resolve_config_path / existing_project_file |
| 项目根目录 | 当前工作目录 cwd |
DEER_FLOW_PROJECT_ROOT |
project_root() |
| 运行时状态目录 | 项目根下 .deer-flow |
DEER_FLOW_HOME |
runtime_home() |
| 技能目录 | 项目根下 skills/ |
DEER_FLOW_SKILLS_PATH 或配置项 skills.path |
skills_config.py |
几个值得注意的实现细节:
DEER_FLOW_PROJECT_ROOT有强校验:project_root()会 resolve 该路径,若目录不存在或不是目录,直接抛ValueError。这意味着“指错路径”不会静默退化为当前目录,而是启动即失败,便于定位问题。DEER_FLOW_HOME优先于项目根推导:runtime_home()在设置该变量时返回其 resolve 结果,否则回退到project_root() / ".deer-flow"。数据库默认值sqlite_dir: .deer-flow/data(见 app_config.py 的CONFIG_FILE_DATABASE_DEFAULTS)也落在该目录下,因此移动DEER_FLOW_HOME等价于整体迁移运行时状态。- 相对路径的解析基准:
resolve_path将相对路径一律相对项目根解析,而不是相对配置文件位置。
三、config.yaml 的四级定位顺序
当后端需要找到 config.yaml 时,AppConfig.resolve_config_path(app_config.py)按以下优先级依次查找:
- 代码显式传入的
config_path参数:文件不存在时抛FileNotFoundError; DEER_FLOW_CONFIG_PATH环境变量:同样要求文件必须存在,不存在即抛错;- 项目根目录下的
config.yaml:项目根由DEER_FLOW_PROJECT_ROOT决定,未设置时取当前工作目录(existing_project_file(("config.yaml",))); - 遗留的 monorepo 兼容位置:
_legacy_config_candidates()返回backend/config.yaml与仓库根config.yaml两个候选,用于兼容历史目录结构。
四级都未命中时抛出:
FileNotFoundError: `config.yaml` file not found in the project root or
legacy backend/repository root locations
官方推荐仍将 config.yaml 放在项目根(deer-flow/config.yaml),理由正是上面第 3 级是主路径,且 make config-upgrade 等脚本也优先按该约定解析。
配置不是加载一次就结束:热重载机制
get_app_config() 返回的是缓存的单例,但它并非“只读缓存”。每次调用都会重新 resolve_config_path,并比较解析路径、文件 mtime 与内容签名(app_config.py):一旦 config.yaml 被修改,下一次访问会自动重新加载并在日志中记录 Config file content signature changed, reloading AppConfig。部分子系统(如 checkpointer)在配置变更时还会触发 reset_checkpointer() / reset_store() 重建单例。需要注意:并非所有字段都可热更新——重启才生效的字段清单由 reload_boundary 模块维护(示例配置注释中也提到 database 属于 restart-required 字段),修改这类配置后应重启 Gateway。
四、配置版本管理与升级
config.example.yaml 第 18 行声明 config_version: 39,它用于检测你的本地配置是否落后。加载流程中的 _check_config_version(app_config.py)会:
- 从
config.yaml所在目录逐级向上找config.example.yaml(最多 5 层); - 比较两个文件中的
config_version,用户版本低于示例版本时打印警告,提示运行make config-upgrade。
make config-upgrade 对应 scripts/config-upgrade.sh,其工作过程是:
- 依次应用版本化迁移(例如 v1 迁移会把
src.community./src.sandbox.等旧模块路径批量替换为deerflow.*); - 把
config.example.yaml中缺失的新字段递归合并进你的配置(只补缺失键,不改写已有值); - 修改前自动备份为
config.yaml.bak(该文件同样被 .gitignore 忽略)。
此外仓库还提供 make config(运行 scripts/configure.py,若本地已有配置则中止)与交互式向导 make setup(scripts/setup_wizard.py),以及用于自检的 make doctor(scripts/doctor.py),可作为配置初始化后的健康检查手段。
五、沙箱镜像预热(可选但推荐)
如果你在 config.yaml 的 sandbox.use 中启用了容器沙箱(deerflow.community.aio_sandbox:AioSandboxProvider),强烈建议在首次运行前预拉取镜像:
# 从项目根目录执行
make setup-sandbox
为什么建议预热?
- 沙箱镜像体积约 500MB+,若不在预热,首次 Agent 执行时会边拉取边等待,造成明显的长等待;
- 预热过程有清晰的进度输出,避免首次使用 Agent 时被“卡住”误导。
跳过此步骤不会导致失败——镜像会在第一次 Agent 执行时自动拉取,耗时取决于网络。
从 scripts/setup-sandbox.sh 的实现可以看到更多细节:
- 脚本会先
grep你config.yaml中sandbox:段下未注释的image:字段,找到则拉取该镜像; - 未找到时回退到内置默认镜像
enterprise-public-cn-beijing.cr.volces.com/vefaas-public/all-in-one-sandbox:1.11.0(固定版本而非:latest,因为镜像源的:latest标签冻结在缺少/v1/bash/*路由的旧 digest 上,相关背景见 config.example.yaml 沙箱段注释); - 若拉取的是默认镜像而配置中并无显式
sandbox.image,脚本会明确警告:预热镜像不等于运行时使用它,需要在config.yaml中显式写出sandbox.image才会真正生效; - macOS 上检测到 Apple Container 时会优先走
container image pull,否则使用docker pull。
config.example.yaml 的沙箱段同时给出了 Local / AIO 容器 / BoxLite / Provisioner 等多种 provider 的注释示例,切换沙箱方案时可直接取消对应注释。
六、故障排查
1. 找不到配置文件
先让后端告诉你它正在查找哪里:
# 进入 deer-flow/backend 后执行,打印后端实际解析出的配置路径
cd deer-flow/backend
python -c "from deerflow.config.app_config import AppConfig; print(AppConfig.resolve_config_path())"
如果解析失败,按顺序检查:
- 确认已执行
cp config.example.yaml config.yaml; - 确认你位于项目根目录,或已设置
DEER_FLOW_PROJECT_ROOT; ls -la config.yaml确认文件确实存在。
对照上文“四级定位顺序”即可判断是走到了哪一级失败:参数/环境变量指定了不存在的路径时错误信息会带具体路径;走到第 3、4 级仍找不到时则是上述通用 FileNotFoundError。
2. 权限被拒绝(Permission denied)
config.yaml 含密钥,建议收紧文件权限:
chmod 600 ../config.yaml # 保护敏感配置(在 backend/ 目录下执行,指向项目根的 config.yaml)
七、进一步阅读
- 配置指南:完整配置项详解;
- 架构总览:系统架构;
- 示例配置文件:所有模型、工具与沙箱选项的带注释范例;
- 配置热重载边界 与
backend/packages/harness/deerflow/config/reload_boundary.py:哪些字段可热更新、哪些需重启; - 相关测试可参考 test_app_config_reload.py 与 test_config_version.py,覆盖热重载与版本检查行为。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0622
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00