主题
deer-flow 引擎配置体系
本章目标:
- 看懂引擎两个配置文件
config.yaml(模型/工具/沙箱/记忆…)与extensions_config.json(MCP/技能)的职责分工- 掌握配置解析三件套:路径优先级、
$ENV变量解析、use:反射加载- 弄清 a-cdm 在 vendored 引擎上动了哪些配置项,以及为什么这么动
TL;DR
引擎配置分两层:deer-flow/config.yaml 是主配置(模型矩阵、工具、沙箱、技能、记忆、摘要、checkpointer、guardrails 等),deer-flow/extensions_config.json 是运行时可改的扩展配置(MCP servers + 技能开关)。配置由 AppConfig.from_file() 按"参数 > DEER_FLOW_CONFIG_PATH > backend/ > 项目根"优先级加载,$VAR 解析成环境变量,use: 字段通过反射 resolve_variable/resolve_class 动态加载实现类。a-cdm 在此基础上做了三处关键定制:sandbox.allow_host_bash: true、Kingdee ERP wiki 目录 mount、agents_api.enabled: true。
Overview(为什么用"配置驱动 + 反射加载"而不是硬编码)
引擎要同时支持火山方舟 9 个模型、多种 web 搜索 provider、本地/Docker 两种沙箱、可插拔 guardrail —— 如果这些都写死在代码里,换一个模型或工具就要改代码、重部署。
deer-flow 的解法是配置即装配清单:config.yaml 里每个 model/tool/sandbox/guardrail 都带一个 use: 字段,值是 package.module:ClassName 形式的类路径,引擎启动时用反射把它实例化。这意味着"加一个新模型""换一个搜索 provider""切沙箱实现"都只改 YAML 不改代码。a-cdm 在 vendored 引擎上的定制也大量利用了这一点 —— 不改框架代码,只改 config.yaml。
Architecture:两个配置文件 + 解析三件套
| 文件 | 内容 | 可运行时改 | 加载入口 | Source |
|---|---|---|---|---|
config.yaml | 模型/工具/沙箱/技能/记忆/摘要/checkpointer/guardrails/circuit_breaker | 部分(mtime 自动 reload) | AppConfig.from_file() | deer-flow/config.yaml:1-15 |
extensions_config.json | mcpServers + skills 开关 | ✓(Gateway API 写) | extensions_config.py | deer-flow/extensions_config.json |
配置 schema 在 deer-flow/backend/packages/harness/deerflow/config/ 下按子系统拆成 20+ 个文件(model_config.py、sandbox_config.py、memory_config.py…),由 app_config.py:60-70 的 AppConfig Pydantic 模型聚合,model_config = ConfigDict(extra="allow") 允许未知字段不报错。
解析三件套:
- 路径优先级(
app_config.py:72-95):显式config_path参数 >DEER_FLOW_CONFIG_PATH环境变量 > 默认候选(backend/ 或仓库根)。找不到抛FileNotFoundError。 - 配置版本检测(
app_config.py:114):config_version字段比对 example 版本,过期发 warning,make config-upgrade自动合并新字段。当前config.yaml:15为config_version: 7。 $VAR环境变量解析(app_config.py:116):值以$开头的解析成环境变量,如api_key: $VOLCENGINE_API_KEY。
反射加载(reflection/resolvers.py):
resolve_variable("pkg.mod:name", expected_type)(:25):按module:attr拆分,import_module+getattr,可选isinstance校验。模块缺失时给出可操作的安装提示(:54)。resolve_class("langchain_openai:ChatOpenAI", base_class)(:73):内部调resolve_variable,再校验是不是base_class子类。
这就是为什么 config.yaml 里 model 写 use: deerflow.models.patched_deepseek:PatchedChatDeepSeek、tool 写 use: deerflow.sandbox.tools:bash_tool、sandbox 写 use: deerflow.sandbox.local:LocalSandboxProvider —— 全是反射目标。
Components:config.yaml 主要段落
| 段 | 作用 | a-cdm 值/定制 | Source |
|---|---|---|---|
models[] | LLM 配置,use/supports_thinking/supports_vision/thinking 开关 | 火山方舟 9 模型 + jointpilot 网关 | deer-flow/config.yaml:37-211 |
tool_groups[] / tools[] | 工具分组与定义 | web/file:read/file:write/bash 四组 | deer-flow/config.yaml:509-636 |
tool_search | MCP 工具延迟加载 | enabled: false | deer-flow/config.yaml:647-648 |
sandbox | 沙箱 provider + 选项 | allow_host_bash: true + Kingdee mount | deer-flow/config.yaml:666-691 |
skills | 技能目录 host/容器路径 | container_path: /mnt/skills | deer-flow/config.yaml:802-811 |
title | 自动标题生成 | enabled: true 6 词 60 字 | deer-flow/config.yaml:824-828 |
summarization | 长对话自动摘要 | enabled: true,token 阈值 15564 | deer-flow/config.yaml:836-876 |
memory | 长期记忆 | enabled: true,max_facts 100 | deer-flow/config.yaml:883-891 |
agents_api | 自定义 agent 管理 API | enabled: true | deer-flow/config.yaml:898-901 |
skill_evolution | agent 自主写 skill | enabled: false | deer-flow/config.yaml:907-909 |
checkpointer | 嵌入式 client 状态持久化 | type: sqlite checkpoints.db | deer-flow/config.yaml:935-937 |
guardrails / circuit_breaker | 工具授权 / LLM 熔断 | 默认注释(未启用) | deer-flow/config.yaml:1054-1095 |
a-cdm 的三处关键配置定制
vendored 引擎默认配置是"安全保守"的,a-cdm 按内部可信团队的实际需求改了三处,每处都有明确写在 config.yaml 注释里的理由:
| 配置项 | 默认 | a-cdm 值 | 理由(注释原文) | 安全标注 | Source |
|---|---|---|---|---|---|
sandbox.allow_host_bash | false | true | 内部可信团队、非公开暴露,启用以支持自研 skill | ⚠️ 放开主机 shell 隔离;长期应迁 AioSandbox | deer-flow/config.yaml:671-673 |
sandbox.mounts | 无 | /data/erp-wiki/kingdee → /mnt/kingdee | 给 Agent 读 Kingdee ERP wiki | 非只读(read_only: false) | deer-flow/config.yaml:680-683 |
agents_api.enabled | false | true | 让"智能专家"创建/管理流程可用 | 生产对外前需 Caddy forward_auth 覆盖此路径 | deer-flow/config.yaml:898-901 |
sandbox.allow_host_bash: true 是其中风险最高的:LocalSandboxProvider 不是安全隔离边界,开了它等于让 Agent 在宿主机执行 shell。a-cdm 接受这个权衡(内部可信、非公开)并在注释里写明长期应迁移到 AioSandboxProvider(docker-in-docker 真隔离)。这条与"沙箱架构"章和红线 CLAUDE.md(安全)直接相关。
extensions_config.json 里 mcpServers.filesystem 默认 enabled,指向 .llm-wiki-clone/wiki —— 这是链路 B(Agent 通过 MCP filesystem 读 llm-wiki 知识库)的本地配置;skills.weekly-report.enabled: true 打开了周报 pipeline 用的技能。
Configuration(配置缓存与运行时刷新)
| 行为 | 机制 | Source |
|---|---|---|
| 配置缓存 | get_app_config() 缓存解析结果 | deer-flow/backend/CLAUDE.md(Config Caching) |
| 自动 reload | 路径变化或文件 mtime 增大时自动重载 | 同上,使 Gateway/LangGraph 读取与编辑对齐 |
| 运行时改 MCP/技能 | Gateway API PUT /api/mcp/config / PUT /api/skills/{name} 写 extensions_config.json | deer-flow/extensions_config.json |
| 配置版本过期 | _check_config_version 发 warning | deer-flow/backend/packages/harness/deerflow/config/app_config.py:114 |
Common Pitfalls / 实战 Tips
config.yaml推荐放项目根不是 backend/:优先级里 backend/ 在前但项目根是推荐位置(app_config.py:79),a-cdm 的deer-flow/config.yaml就在引擎根。- 改
config.yaml不一定要重启:有 mtime 自动 reload;但改.env引用的环境变量必须重启进程(env 在进程启动时读)。 use:写错会在启动期 ImportError 而非静默失败:resolve_variable对缺模块给出uv add xxx式提示(resolvers.py:54),这是 fail-fast 设计。allow_host_bash: true是有意为之:不要"修正"成 false,它是 a-cdm 支持自研 skill 的前提;真要收紧应迁 AioSandbox 而非简单关开关。
References
deer-flow/config.yaml:1-1095— 引擎主配置全文(本章主源)deer-flow/extensions_config.json— MCP servers + 技能开关deer-flow/backend/packages/harness/deerflow/config/app_config.py:55-129— AppConfig 聚合 + from_file 加载链deer-flow/backend/packages/harness/deerflow/reflection/resolvers.py:25-95—use:反射加载实现deer-flow/backend/packages/harness/deerflow/config/— 20+ 子配置 schema 文件deer-flow/backend/CLAUDE.md— 配置版本/缓存/扩展配置机制说明(线索,已回源核实)
Related Pages
| Page | Relationship |
|---|---|
| AI 角色注册表与模型矩阵 | 本章 config.yaml models 段与该章 ai_registry 是两套并行的模型配置体系 |
| 环境变量、凭据与降级开关 | 本章 $VAR 解析的环境变量在该章详列 |
| 沙箱架构与文件工具 | 本章 sandbox.allow_host_bash 定制的安全后果在该章详解 |
| SKILL 技能系统 | 本章 skills 段 + extensions_config 技能开关在该章展开 |
| 长期记忆机制 | 本章 memory 段配置项在该章对应到机制 |