Skip to content

deer-flow

12 posts with the tag “deer-flow”

DeerFlow 子Agent委派实现说明

DeerFlow的子Agent系统是基于LangGraph构建的任务委派机制,允许主Agent将复杂任务委托给专门的子Agent执行,实现上下文隔离、并行处理和专业化分工。


组件位置职责
执行引擎packages/harness/deerflow/subagents/executor.py子Agent同步/异步执行、线程池管理、任务状态跟踪、超时控制
注册中心packages/harness/deerflow/subagents/registry.py管理可用子Agent配置,支持config.yaml配置覆盖
工具入口packages/harness/deerflow/tools/builtins/task_tool.py对外暴露task工具,是父Agent调用子Agent的统一入口
内置子Agentpackages/harness/deerflow/subagents/builtins/提供两种开箱即用的子Agent类型:general-purpose(通用型)、bash(命令行专家)
限流中间件packages/harness/deerflow/agents/middlewares/subagent_limit_middleware.py强制限制最大并发子Agent数为3,避免资源耗尽

1. 触发阶段:父Agent调用task工具

Section titled “1. 触发阶段:父Agent调用task工具”

当父Agent需要委派任务时,调用task工具,传入参数:

  • description: 3-5字的任务简短描述(用于日志和前端展示)
  • prompt: 给子Agent的详细任务指令,需要具体明确
  • subagent_type: 子Agent类型(general-purposebash
  • 可选max_turns: 子Agent最大交互轮次,覆盖默认配置
  1. 从注册中心获取对应类型的子Agent默认配置
  2. 应用config.yaml中的自定义配置(如超时时间覆盖)
  3. 注入当前已启用的技能提示到子Agent的系统提示词
  4. 若指定了max_turns,覆盖默认配置值

子Agent自动继承父Agent的运行上下文,保持环境一致性:

  • 沙箱状态(sandbox_state):保持文件系统访问权限和路径映射一致
  • 线程数据(thread_data):共享线程级别的配置和状态
  • 线程ID(thread_id):关联到同一个会话线程
  • 模型配置(parent_model):可配置继承父Agent使用的LLM模型
  • 追踪ID(trace_id):统一分布式追踪ID,关联父子Agent的日志
  • 子Agent的工具集通过get_available_tools()获取,但强制关闭子Agent功能subagent_enabled=False),防止递归嵌套调用
  • 根据子Agent配置的工具白名单/黑名单进一步过滤可用工具
    • general-purpose:拥有除task外的所有工具权限
    • bash:仅拥有命令执行相关工具权限
  1. 创建SubagentExecutor执行器实例
  2. 任务提交到双层线程池异步执行:
    • _scheduler_pool(3 worker):负责任务调度、状态管理、超时控制
    • _execution_pool(3 worker):负责实际的子Agent逻辑执行
  3. 子Agent创建独立的LangChain Agent实例,使用对应类型的专用系统提示词,运行在隔离上下文
  4. 以stream模式执行,实时收集AI生成的所有中间消息,用于后续调试和审计
  5. 父Agent调用task工具后会通过5秒间隔轮询等待子Agent执行完成(对当前会话是同步阻塞的),但子Agent运行在独立线程池,不会阻塞其他会话的Agent执行

执行过程中通过SSE流实时推送事件到前端:

  • task_started:任务开始执行
  • task_running:执行中,包含子Agent的中间输出消息(1-based索引)
  • task_completed:任务成功完成,返回最终结果
  • task_failed:任务执行失败,返回错误信息
  • task_timed_out:任务执行超时

子Agent执行完成后,将最终结果返回给父Agent,父Agent可以基于这个结果继续后续处理,完成后自动清理后台任务记录,避免内存泄漏。


  • 子Agent运行在独立的线程和执行上下文,不会污染父Agent的状态
  • 工具集独立配置,权限按需分配
  • 子Agent默认没有task工具权限,无法嵌套调用其他子Agent,避免无限递归
  • 线程池层面的执行超时:可配置,默认15分钟
  • 轮询层面的超时保护:超时时间+60s缓冲,作为兜底机制防止任务卡死
  • 最大并发子Agent数为3,由SubagentLimitMiddleware中间件自动拦截超过限制的工具调用
  • 支持通过配置文件自定义子Agent超时时间
  • 注册中心设计支持扩展更多内置子Agent类型

类型适用场景工具权限
general-purpose复杂多步骤任务、探索性研究、需要多种工具配合的工作task外的所有工具
bashGit操作、构建流程、批量命令执行、大量命令输出的场景仅命令行相关工具

config.yaml中可以配置子Agent的超时时间:

subagents:
enabled: true
timeouts:
general-purpose: 900 # 15分钟
bash: 300 # 5分钟

Plan Mode 与 TodoList 实现说明

Plan Mode是DeerFlow提供的任务规划与进度跟踪功能,通过TodoList中间件实现,允许Agent将复杂任务拆分为多步执行,并实时跟踪进度,为用户提供透明的工作流程可见性。


组件位置职责
Todo中间件packages/harness/deerflow/agents/middlewares/todo_middleware.py扩展LangChain内置TodoListMiddleware,添加上下文丢失检测和提醒注入功能
ThreadState定义packages/harness/deerflow/agents/thread_state.py定义todos字段存储任务列表状态
中间件注册packages/harness/deerflow/agents/lead_agent/agent.py动态根据Plan Mode开关决定是否加载Todo中间件
write_todos工具LangChain内置,由TodoListMiddleware自动提供任务列表管理工具,支持创建、更新、完成任务

Plan Mode通过runtime配置参数动态控制,无需修改静态配置:

  • 在调用Agent时,通过config.configurable.is_plan_mode = True开启Plan Mode
  • 开启后,_build_middlewares函数会自动创建并加载TodoMiddleware
  • 关闭时,Todo中间件不会被加载,Agent也不会拥有write_todos工具权限

TodoMiddleware继承自LangChain的TodoListMiddleware,扩展了上下文丢失保护机制:

前置钩子(before_model/abefore_model

Section titled “前置钩子(before_model/abefore_model)”

在每次调用LLM之前执行:

  1. 检查当前状态中是否存在todos任务列表
  2. 检查最近的消息历史中是否包含write_todos工具调用(即任务列表是否还在上下文窗口中)
  3. 检查是否已经注入过todo提醒消息,避免重复
  4. 如果任务列表存在但已经不在上下文窗口中,自动注入系统提醒消息,包含当前所有任务的状态
<system_reminder>
Your todo list from earlier is no longer visible in the current context window,
but it is still active. Here is the current state:
- [pending] 任务1
- [in_progress] 任务2
- [completed] 任务3
Continue tracking and updating this todo list as you work.
Call `write_todos` whenever the status of any item changes.
</system_reminder>
  • 任务列表存储在ThreadStatetodos字段中,类型为list[Todo]
  • 每个Todo对象包含:
    • content: 任务描述
    • status: 任务状态(pending/in_progress/completed
    • activeForm: 任务进行时的描述(可选)

DeerFlow对内置的TodoListMiddleware进行了定制,添加了严格的使用规则和最佳实践提示:

  • 必须立即标记完成:完成任务后立即更新状态,不要批量更新
  • 单任务进行中:同一时间只能有一个任务处于in_progress状态(可并行任务除外)
  • 实时更新:工作过程中实时更新任务列表,给用户提供可见性
  • 避免滥用:少于3步的简单任务不要使用Todo功能,直接完成即可
  • 复杂多步骤任务(≥3步)
  • 需要仔细规划的非平凡任务
  • 用户明确要求使用任务列表
  • 用户提供多个任务(编号或逗号分隔列表)
  • 需要根据中间结果动态调整计划的任务

当对话历史被截断(例如被SummarizationMiddleware summarization)导致原始write_todos调用被移出上下文窗口时,中间件会自动注入提醒消息,确保Agent不会忘记当前的任务列表。

内置规则确保任务管理的规范性:

  • 只有完全完成的任务才能标记为completed
  • 遇到阻塞时保持任务为in_progress,并新增解决阻塞的任务
  • 自动提醒实时更新状态,避免进度跟踪滞后

Plan Mode完全通过runtime参数控制,无需修改静态配置文件,可按需为每个会话独立开启或关闭。

同时实现了同步before_model和异步abefore_model钩子,兼容同步和异步两种Agent运行模式。

基于LangChain官方TodoListMiddleware扩展,保持了与LangGraph生态的兼容性,同时添加了适合生产环境的增强功能。


在创建Agent运行时传入配置:

config = {
"configurable": {
"is_plan_mode": True,
# 其他配置...
}
}

Agent会根据任务复杂度自动决定是否调用write_todos工具,示例调用:

{
"name": "write_todos",
"parameters": {
"todos": [
{
"content": "分析子Agent委派实现",
"status": "in_progress",
"activeForm": "分析子Agent委派实现中"
},
{
"content": "撰写实现文档",
"status": "pending",
"activeForm": "撰写实现文档中"
},
{
"content": "复核文档正确性",
"status": "pending",
"activeForm": "复核文档正确性中"
}
]
}
}

Agent在完成任务或切换任务时自动调用write_todos更新状态:

{
"name": "write_todos",
"parameters": {
"todos": [
{
"content": "分析子Agent委派实现",
"status": "completed",
"activeForm": "分析子Agent委派实现中"
},
{
"content": "撰写实现文档",
"status": "in_progress",
"activeForm": "撰写实现文档中"
},
{
"content": "复核文档正确性",
"status": "pending",
"activeForm": "复核文档正确性中"
}
]
}
}

组件交互方式
SummarizationMiddlewareTodo中间件在summarization之后执行,检测summarization是否导致任务列表被移出上下文窗口
ClarificationMiddlewareTodo中间件在ClarificationMiddleware之前执行,确保Agent可以在需要澄清问题时仍然能够管理任务列表
前端UI任务状态变化会通过SSE事件推送到前端,实时展示进度
子Agent系统Plan Mode下的任务可以委派给子Agent执行,状态更新会同步回主任务列表

  1. Plan Mode默认是关闭的,需要显式开启
  2. 任务列表存储在会话状态中,会话结束后不会持久化
  3. 中间件自动处理上下文丢失问题,无需人工干预
  4. 严格遵守内置规则可以有效提升任务执行的透明度和可追溯性

Skill 系统实现对比分析文档

本文档深入分析DeerFlow系统中Skill功能的实现机制,并与官方Claude Code的Skill系统实现进行对比,总结两者的异同点及背后的设计考量。

DeerFlow的Skill系统是一套可扩展的技能机制,允许用户安装、管理和使用预定义的工作流模板,每个Skill包含最佳实践、操作框架和相关资源,为AI Agent提供特定任务的标准化执行流程。

每个Skill以独立目录形式存在,核心文件为SKILL.md,采用Markdown + YAML Frontmatter格式:

  • 必填字段: name(技能名称,短横线命名法)、description(技能描述)
  • 可选字段: licenseallowed-toolsmetadatacompatibilityversionauthor
  • 正文内容: 技能的具体执行流程、使用说明、参考资源等
skills/
├── public/ # 公共技能,随代码库提交
│ └── [skill-name]/
│ ├── SKILL.md
│ └── 其他资源文件
└── custom/ # 用户自定义安装的技能,git忽略
└── [skill-name]/
└── SKILL.md
  1. 扫描: loader.pyload_skills()函数递归扫描publiccustom目录,查找所有SKILL.md文件
  2. 解析: parser.pyparse_skill_file()提取YAML Frontmatter,解析为Skill数据对象
  3. 状态同步: 从extensions_config.json读取技能启用状态,更新Skill.enabled属性
  4. 返回: 按名称排序的Skill列表
  1. 注入: 已启用的技能会在Agent启动时以XML格式注入到系统提示词中,包含技能名称、描述和文件路径
  2. 触发: 当用户请求匹配技能使用场景时,Agent自动调用read_file读取技能内容
  3. 执行: Agent按照技能定义的步骤执行任务,按需加载技能目录下的其他参考资源
  • 安装安全:压缩包路径校验,防止目录穿越攻击,自动跳过符号链接,总大小限制512MB
  • 内容校验:严格验证SKILL.md Frontmatter格式和字段合法性
  • 权限控制:自定义技能与公共技能隔离,技能在容器内以只读方式挂载
模块文件路径功能说明
类型定义/backend/packages/harness/deerflow/skills/types.pySkill数据类定义
加载逻辑/backend/packages/harness/deerflow/skills/loader.py技能扫描、加载逻辑
解析逻辑/backend/packages/harness/deerflow/skills/parser.pySKILL.md文件解析
安装逻辑/backend/packages/harness/deerflow/skills/installer.py技能安装、安全校验
API路由/backend/app/gateway/routers/skills.py技能管理API接口
运行时注入/backend/packages/harness/deerflow/agents/lead_agent/prompt.py技能注入Agent系统提示词

二、官方 Claude Code Skill 实现分析

Section titled “二、官方 Claude Code Skill 实现分析”

Skills是Claude Code的模块化扩展组件,用于为Claude提供特定领域的专业知识、标准化工作流、工具集成能力和业务逻辑,将通用AI代理转变为面向特定任务的专业化代理。

每个Skill完全自包含,核心文件为SKILL.md

  • YAML Frontmatter必填字段: name(技能名称)、description(触发条件/使用场景描述)
  • 可选字段: versionauthorlicenseallowed-tools
  • 正文内容: 技能的系统提示、执行规则、工作流步骤、工具使用规范等
  • 面向Agent类型的Skill还支持JSON格式定义,包含identifierwhenToUsesystemPrompt字段
skill-name/
├── SKILL.md # 核心技能定义文件(必选)
├── references/ # 参考文档资源(可选)
├── examples/ # 示例代码/配置(可选)
└── scripts/ # 配套执行脚本(可选)

所有Skill统一存放在插件的skills/目录下的独立子目录中。

采用三级渐进式加载机制:

  1. 启动扫描阶段: Claude Code启动时自动扫描所有插件的skills/目录,仅加载元数据(name/description/version)到常驻内存
  2. 触发加载阶段: 当用户查询或任务上下文匹配到技能的description描述时,加载对应技能的SKILL.md正文内容到当前会话上下文
  3. 按需加载阶段: 技能执行过程中需要参考文档、示例、脚本等资源时,动态加载对应目录下的资源文件
  1. 触发方式:
    • 隐式触发:任务上下文和技能description中的触发描述匹配时自动激活
    • 显式触发:用户执行/skill <skill-name> [args]命令主动调用
  2. 执行流程:
    • 技能激活后,系统将技能定义的规则、工作流、系统提示词注入当前会话上下文
    • Claude按照技能定义的逻辑和约束执行任务,可调用技能配套的脚本、工具和资源
  3. 结果处理: 技能执行结果直接返回会话上下文,可作为后续任务的输入
  • 插件化架构: Skill是Claude Code插件系统的核心组件之一,与commands、agents、hooks、MCP工具等组件并行
  • 分层披露设计: 三级加载机制避免不必要的上下文占用,平衡性能和功能完整性
  • 完全自包含设计: 每个Skill独立打包、分发、安装,无外部依赖
  • 无侵入集成: 技能不需要编译或打包,直接以纯文本格式分发
维度共性描述
定义格式都采用SKILL.md作为核心定义文件,使用YAML Frontmatter + Markdown正文格式,必填字段都包含namedescription
存储结构都采用独立目录存储每个Skill,支持配套资源文件(参考文档、示例、脚本等)
核心目标都是为了提供标准化的工作流模板,扩展Agent的专业能力,处理特定领域的复杂任务
执行逻辑都是将技能内容注入到Agent的上下文,让Agent按照技能定义的规则执行任务
扩展性都支持用户自定义技能,无需修改核心代码即可扩展功能
安全性都有严格的安全校验机制,防止恶意技能注入和攻击
维度DeerFlow Skill系统官方Claude Code Skill系统
加载机制一次性加载所有已启用技能的元数据和路径信息到Agent系统提示采用三级渐进式加载,仅在匹配到触发条件时才加载技能正文,按需加载资源
触发方式仅支持隐式触发,依赖Agent自动识别匹配场景支持隐式自动触发和显式命令触发(/skill命令)
架构定位是DeerFlow系统的内置核心功能,与Agent系统深度集成是Claude Code插件系统的一部分,与其他插件组件(commands、agents等)并行
技能分类明确分为public(内置公共技能)和custom(用户自定义技能)两类无明确分类,由插件目录结构自然区分
状态管理有完整的启用/禁用状态管理,通过extensions_config.json配置,支持动态修改依赖插件的启用/禁用机制,无单独的技能状态管理
资源加载Agent需要主动调用read_file读取技能内容系统自动加载匹配的技能内容到上下文,无需Agent主动读取
参数支持无显式参数传递机制,参数从会话上下文提取支持通过Skill工具的args参数显式传递参数
  • 深度集成优先: DeerFlow作为专门的Agent协作平台,需要技能系统与核心Agent流程深度耦合,因此采用一次性注入所有技能信息的方式,确保Agent可以随时访问所有可用技能
  • 集中管理优先: 明确的技能分类和状态管理机制,方便平台管理员统一管控可用技能,适合企业级部署场景
  • 安全性优先: 严格的容器隔离和只读挂载机制,保障多租户环境下的技能使用安全
  • 性能优先: 三级渐进式加载机制最大限度减少不必要的上下文占用,提升会话响应速度,适合轻量级客户端场景
  • 灵活性优先: 支持显式命令调用和参数传递,用户可以更灵活地控制技能的使用时机和方式
  • 扩展性优先: 作为插件系统的一部分,技能可以与其他插件组件无缝协作,方便第三方开发者扩展功能

DeerFlow的Skill系统可以从官方实现中借鉴以下优化点:

  1. 引入渐进式加载机制,减少系统提示词长度,提升Agent响应效率
  2. 增加显式/skill命令调用支持,让用户可以主动触发特定技能
  3. 支持技能参数显式传递,提升技能使用的灵活性
  4. 优化技能匹配算法,提升隐式触发的准确率

DeerFlow 沙箱执行环境实现分析

DeerFlow的沙箱系统采用抽象接口+多实现的设计模式,提供两种执行模式:本地文件系统模式和Docker容器隔离模式,通过统一的接口对外提供服务。

Sandbox (接口) → 定义沙箱基本操作:execute_command、read_file、write_file、list_dir、update_file
SandboxProvider (接口) → 定义沙箱生命周期管理:acquire(获取)、get(查询)、release(释放)
  • 适用场景:开发环境、低安全要求场景
  • 实现原理
    • 单例模式,所有线程共享同一个沙箱实例
    • 通过路径映射机制实现逻辑隔离:
      • 虚拟路径:Agent 看到的统一路径 /mnt/user-data/{workspace,uploads,outputs}/mnt/skills
      • 实际路径:物理上存储在 backend/.deer-flow/threads/{thread_id}/user-data/... 和项目根目录的 skills/
    • 命令执行时自动转换路径:
      • 输入:将命令中的虚拟路径替换为实际本地路径,优先匹配最长前缀避免歧义
      • 输出:将执行结果中的本地路径替换回虚拟路径,对Agent完全透明
    • Shell自动检测:优先使用zsh,其次bash,最后sh,保证跨平台兼容性
  • 特点:轻量、无额外依赖、启动快,但隔离性较弱
  • 适用场景:生产环境、高安全要求场景
  • 核心特性
    • 两种后端
      • 本地Docker后端:直接管理本地Docker容器生命周期
      • 远程K8s后端:通过Provisioner服务动态创建K8s Pod作为沙箱
    • 暖池机制:释放的沙箱容器不会立即销毁,放入暖池等待复用,避免冷启动开销
    • 空闲超时管理:默认10分钟无活动自动销毁容器,节省资源
    • 并发控制:默认最大3个并发沙箱容器,超过时采用LRU策略销毁最旧的暖池容器;并发限制为软限制,活跃沙箱不会被强制销毁
    • 跨进程一致性:通过线程ID生成确定性沙箱ID,支持多进程/多Pod环境下的沙箱发现
    • 跨进程锁机制:通过文件锁防止多个进程同时为同一个线程创建沙箱导致的冲突
  • 安全特性
    • 每个线程独立容器,完全隔离,进程、文件系统、网络都互相隔离
    • 工作目录、上传目录、输出目录独立挂载,每个线程只能访问自己的数据
    • 技能目录只读挂载,防止Agent修改系统技能
    • ACP工作区只读挂载,仅允许Agent读取ACP代理的执行结果
    • 支持自定义环境变量和额外挂载配置

沙箱的生命周期由SandboxMiddleware中间件统一管理:

  1. 会话开始时调用provider.acquire(thread_id)获取沙箱
  2. 会话过程中通过provider.get(sandbox_id)获取沙箱实例执行操作
  3. 会话结束时调用provider.release(sandbox_id)释放沙箱(Docker模式下放入暖池)

沙箱功能被封装为统一的工具集提供给Agent使用:

  • bash:执行命令,自动处理路径转换和错误
  • ls:目录列表,返回tree格式
  • read_file:读取文件内容,支持行范围
  • write_file:写入/追加文件,自动创建目录
  • str_replace:字符串替换,支持批量替换

config.yaml中通过sandbox.use字段指定沙箱实现:

# 本地模式
sandbox:
use: deerflow.sandbox.local.local_sandbox_provider:LocalSandboxProvider
# Docker模式
sandbox:
use: deerflow.community.aio_sandbox:AioSandboxProvider
image: enterprise-public-cn-beijing.cr.volces.com/vefaas-public/all-in-one-sandbox:latest
idle_timeout: 600
replicas: 3

这种设计使得沙箱实现可插拔,未来可以轻松扩展支持其他隔离技术(如Kata Containers、WASM等)而不影响上层业务逻辑。

MCP (Model Context Protocol) 系统实现说明

DeerFlow完整集成了MCP(Model Context Protocol)协议,支持无缝对接各类MCP服务器,实现工具能力的动态扩展。系统采用模块化设计,支持多种传输协议、OAuth 2.0认证、运行时热更新、自动缓存等企业级特性,无需修改代码即可通过配置扩展Agent的工具能力。


所有MCP相关代码集中在packages/harness/deerflow/mcp/目录下:

文件职责
mcp/__init__.py模块导出接口,统一暴露核心函数
mcp/cache.pyMCP工具缓存机制,支持自动失效与懒加载
mcp/client.pyMCP客户端实现,支持多传输类型配置构建
mcp/oauth.pyOAuth令牌管理,支持自动刷新与请求头注入
mcp/tools.py工具加载与同步适配,将MCP工具转换为LangChain兼容格式
config/extensions_config.py配置解析系统,定义MCP配置结构与加载逻辑
app/gateway/routers/mcp.pyGateway API层,提供MCP配置的REST管理接口
┌─────────────────────────────────────────────────────────┐
│ Agent Runtime │
└─────────────────┬─────────────────────────────────────────┘
┌─────────────────▼─────────────────────────────────────────┐
│ MCP Tool Cache │
│ (懒加载、自动失效、线程安全) │
└─────────────────┬─────────────────────────────────────────┘
┌─────────────────▼─────────────────────────────────────────┐
│ MultiServerMCPClient │
│ ┌────────────┐ ┌────────────┐ ┌────────────┐ │
│ │ Stdio 服务 │ │ SSE 服务 │ │ HTTP 服务 │ │
│ └────────────┘ └────────────┘ └────────────┘ │
└─────────────────┬─────────────────────────────────────────┘
┌─────────────────▼─────────────────────────────────────────┐
│ OAuth 管理器 │
│ (令牌自动刷新、线程安全、请求头自动注入) │
└─────────────────┬─────────────────────────────────────────┘
┌─────────────────▼─────────────────────────────────────────┐
│ MCP 服务器集群 │
│ (本地进程、远程服务、第三方MCP服务) │
└───────────────────────────────────────────────────────────┘

MCP服务器配置存储在extensions_config.json文件中,示例:

{
"mcpServers": {
"github": {
"enabled": true,
"type": "stdio",
"command": "npx",
"args": ["-y", "@github/mcp-server-github"],
"env": {
"GITHUB_TOKEN": "$GITHUB_TOKEN"
},
"description": "GitHub API 工具集"
},
"internal-api": {
"enabled": true,
"type": "http",
"url": "https://mcp.example.com/tools",
"oauth": {
"enabled": true,
"token_url": "https://auth.example.com/oauth2/token",
"grant_type": "client_credentials",
"client_id": "$CLIENT_ID",
"client_secret": "$CLIENT_SECRET",
"scope": "read write"
},
"description": "内部系统API工具集"
}
}
}

支持三种传输协议:

类型适用场景配置参数
stdio本地MCP服务器,通过子进程启动commandargsenv
sse远程SSE协议的MCP服务器urlheaders
http远程HTTP协议的MCP服务器urlheaders
  1. 显式传入的config_path参数
  2. DEER_FLOW_EXTENSIONS_CONFIG_PATH环境变量
  3. 当前工作目录下的extensions_config.json
  4. 当前工作目录父目录下的extensions_config.json(推荐位置)
  5. 兼容旧版:查找mcp_config.json作为备选
  • 配置中所有以$开头的字符串会自动解析为环境变量
  • 示例:"GITHUB_TOKEN": "$GITHUB_TOKEN"会自动替换为对应环境变量的值
  • 未找到的环境变量自动替换为空字符串,避免运行错误

支持完整的OAuth 2.0客户端认证能力:

  • client_credentials:客户端凭证模式,适用于服务间通信
  • refresh_token:刷新令牌模式,适用于用户级授权场景
  • 自动刷新:提前60秒(可配置refresh_skew_seconds)自动刷新令牌,避免请求时令牌过期
  • 线程安全:每个MCP服务器独立的令牌获取锁,避免并发刷新导致的重复请求
  • 自动注入:工具调用拦截器自动将最新的Authorization头注入到所有MCP请求中
  • 初始化认证:首次连接MCP服务器时自动注入OAuth头,确保工具发现阶段的认证通过
  • 自动发现:自动加载所有启用MCP服务器暴露的工具,无需手动定义
  • 名称隔离:工具名称自动添加服务器前缀,避免不同服务器之间的命名冲突,格式为{server_name}_{tool_name}
  • 同步适配:异步MCP工具自动封装为同步调用,适配DeerFlow的同步执行模型,使用全局线程池避免嵌套事件循环问题
  • 类型转换:自动处理MCP工具参数与LangChain工具格式的转换,上层调用无感知
  • 全局单例缓存:MCP工具加载后全局缓存,避免重复初始化的性能开销
  • 自动失效:通过监控配置文件的修改时间(mtime),配置变更后自动失效缓存,下次访问时重新加载
  • 懒加载:支持首次使用时自动初始化,兼顾冷启动性能和资源占用
  • 线程安全:初始化过程使用异步锁,避免并发场景下的重复初始化问题
# 获取MCP工具(自动初始化、自动缓存)
from deerflow.mcp import get_cached_mcp_tools
tools = get_cached_mcp_tools()
# 手动重置缓存(配置更新后调用)
from deerflow.mcp import reset_mcp_tools_cache
reset_mcp_tools_cache()
  • 配置文件修改后,系统自动检测到mtime变化,缓存自动失效
  • 通过Gateway API更新配置后,自动触发缓存重置
  • 新配置在下次工具调用时自动生效,无需重启LangGraph或Gateway服务
  • 更新过程中不影响现有会话的运行

  1. 初始化触发:应用启动或首次调用MCP工具时,get_cached_mcp_tools()被调用
  2. 配置加载:从extensions_config.json加载所有启用的MCP服务器配置,解析环境变量
  3. OAuth初始化:为需要认证的服务器初始化OAuth令牌管理器,获取初始访问令牌
  4. 客户端创建:构建MultiServerMCPClient实例,连接所有MCP服务器
  5. 工具发现:自动从所有MCP服务器发现并加载工具定义
  6. 工具适配:将异步MCP工具封装为同步调用,添加服务器前缀,存入全局缓存
  7. 工具使用:Agent调用MCP工具时,OAuth拦截器自动注入最新令牌,同步包装器处理异步调用逻辑
  8. 缓存失效:当配置文件被修改时,缓存自动失效,下次访问时重新执行初始化流程

Gateway提供了REST接口用于管理MCP配置:

GET /api/mcp/config

返回所有MCP服务器和技能的配置信息。

PUT /api/mcp/config
Content-Type: application/json

请求体为新的MCP配置,保存到文件后自动重置缓存,新配置立即生效。

注意:更新MCP配置时不会覆盖已有的技能配置,实现MCP与技能配置的独立管理。


  1. 零代码扩展:新增MCP服务器只需修改配置文件,无需修改业务代码
  2. 运行时热更新:配置修改后自动生效,无需重启服务
  3. 多场景适配:支持本地命令行、远程SSE/HTTP等多种MCP服务器部署方式
  4. 企业级安全:完整的OAuth 2.0支持,满足内部API和第三方API的安全访问需求
  5. 高性能设计:缓存机制与自动失效平衡了性能和配置实时性
  6. 兼容现有架构:同步包装器完美适配DeerFlow现有的同步执行模型,无需修改上层调用逻辑

  1. 敏感信息管理:所有API密钥、令牌都通过环境变量传递,不要硬编码在配置文件中
  2. 命名规范:MCP服务器名称使用小写字母和连字符,避免特殊字符
  3. 权限最小化:为MCP服务器配置最小必要的权限,避免过度授权
  4. 版本锁定:本地stdio类型的MCP服务器推荐锁定版本号,避免意外升级导致兼容性问题
  5. 监控告警:对重要的MCP服务器添加健康检查,及时发现服务不可用问题

文件上传与Artifact存储分享实现说明

DeerFlow提供了完整的文件上传和Artifact(Agent生成的文件、网页等)存储分享能力,采用线程隔离的存储架构,结合严格的安全机制,确保文件操作的安全性和可用性。


组件位置职责
上传APIapp/gateway/routers/uploads.py提供文件上传、列表、删除的HTTP接口
上传管理器packages/harness/deerflow/uploads/manager.py上传核心逻辑,包括路径校验、文件存储、格式转换、URL生成
上传中间件packages/harness/deerflow/agents/middlewares/uploads_middleware.py自动将上传文件列表注入到Agent上下文
文件转换工具packages/harness/deerflow/utils/file_conversion.py支持Office文档、PDF等格式自动转换为Markdown
路径配置packages/harness/deerflow/config/paths.py定义虚拟路径到物理路径的映射规则
POST /api/threads/{thread_id}/uploads
Content-Type: multipart/form-data
  • 参数:files 多文件列表
  • 返回:
    {
    "success": true,
    "files": [
    {
    "filename": "document.pdf",
    "physical_path": "/path/to/threads/123/user-data/uploads/document.pdf",
    "virtual_path": "/mnt/user-data/uploads/document.pdf",
    "url": "/api/threads/123/artifacts/mnt/user-data/uploads/document.pdf",
    "size": 102400,
    "converted_md": "/mnt/user-data/uploads/document.pdf.md" // 转换后的Markdown文件(如果支持)
    }
    ]
    }
GET /api/threads/{thread_id}/uploads/list
DELETE /api/threads/{thread_id}/uploads/{filename}
  1. 请求校验:验证thread_id合法性,校验文件名是否包含路径遍历字符
  2. 目录创建:自动创建线程对应的上传目录(如果不存在)
  3. 文件存储:将文件写入物理存储路径
  4. 沙箱同步:非本地沙箱场景下,自动同步文件到沙箱环境
  5. 格式转换:检测文件类型,支持的文档格式自动转换为Markdown
  6. 结果返回:返回文件的物理路径、虚拟路径、访问URL等信息
  • PDF文档(.pdf
  • PowerPoint演示文稿(.ppt, .pptx
  • Excel表格(.xls, .xlsx
  • Word文档(.doc, .docx
{base_dir}/threads/{thread_id}/user-data/uploads/
  • base_dir优先级:
    1. 显式传入的路径参数
    2. DEER_FLOW_HOME环境变量
    3. 开发环境:backend/.deer-flow
    4. 默认:$HOME/.deer-flow
/mnt/user-data/uploads/{filename}

Agent可以直接通过read_file工具使用该路径读取文件内容。

/api/threads/{thread_id}/artifacts/mnt/user-data/uploads/{filename}

UploadsMiddleware中间件在每次Agent执行前自动处理上传文件:

  1. 从当前消息中提取新上传的文件信息
  2. 扫描线程上传目录获取所有历史上传文件
  3. 生成<uploaded_files>标签,包含所有文件的路径、大小等信息
  4. 将文件列表追加到用户消息中,让Agent感知到已上传的文件
  5. Agent可以直接通过虚拟路径读取文件内容

Agent生成的网页、文档、图片等产出物统称为Artifact,系统提供了完整的存储、预览、分享能力。

组件位置职责
Artifact服务APIapp/gateway/routers/artifacts.py提供Artifact访问、下载的HTTP接口
路径解析工具app/gateway/path_utils.py统一处理虚拟路径到物理路径的转换
展示工具packages/harness/deerflow/tools/builtins/present_file_tool.pyAgent调用present_files工具将生成的文件展示给用户
路径配置packages/harness/deerflow/config/paths.py统一的路径映射规则
{base_dir}/threads/{thread_id}/user-data/outputs/
/mnt/user-data/outputs/{filename}

Agent生成文件时需要保存到这个路径下才能被识别为Artifact。

/api/threads/{thread_id}/artifacts/mnt/user-data/outputs/{filename}
  1. 文件生成:Agent生成网页、报告等文件,必须保存到/mnt/user-data/outputs/路径下
  2. 展示调用:Agent调用present_files工具,传入需要展示的文件路径(工具会校验路径必须在/mnt/user-data/outputs/目录下,防止非法路径访问)
  3. 状态更新:工具将文件路径添加到线程状态的artifacts列表中
  4. 前端渲染:前端识别到artifacts列表中的文件,自动生成可访问的链接
  5. 用户访问:用户点击链接即可在线预览或下载文件
GET /api/threads/{thread_id}/artifacts/{virtual_path:path}
  • 支持?download=true参数强制下载文件
  • 自动识别MIME类型,根据文件类型返回对应响应:
    • 活跃内容类型(HTML/XHTML/SVG)强制下载,防止XSS攻击
    • 文本/图片等安全类型支持在线预览
    • 二进制文件默认提供下载
http://{your-deerflow-domain}/api/threads/{thread_id}/artifacts/{virtual_path}
  • URL包含thread_id和文件虚拟路径,可直接分享给其他用户访问
  • 所有访问都会经过权限校验,确保只有授权用户可以访问对应线程的文件

  • 所有路径解析都经过严格的边界检查,确保文件始终在对应线程的目录范围内
  • 自动过滤文件名中的路径遍历字符(..//等),防止目录穿越攻击
  • 每个线程的文件存储在独立的目录中,不同线程之间无法互相访问文件
  • 路径解析时严格校验thread_id与目录的对应关系
  • HTML、XHTML、SVG等包含可执行代码的内容类型强制作为附件下载,不会直接在浏览器中渲染
  • 所有文本内容返回时设置正确的Content-Type和安全Header
  • 上传文件名自动标准化处理,移除路径组件和特殊字符
  • 文件名冲突时自动重命名,避免覆盖现有文件
  • 所有文件访问都需要经过会话权限校验,确保只有线程参与者可以访问对应文件
  • 不允许访问线程目录之外的任何系统文件

  1. 文件大小限制:默认最大100MB,可通过Nginx配置的client_max_body_size调整
  2. 文件名长度:最大255字节
  3. 存储隔离:文件仅在当前线程内可见,无法跨线程访问
  4. 转换耗时:大文档转换为Markdown可能需要几秒到几十秒不等
  5. 存储清理:线程删除时会自动清理对应目录下的所有上传文件和生成的Artifact

前端提供了完整的上传和Artifact访问封装:

  • uploadFiles(threadId, files):上传多个文件到指定线程
  • listUploadedFiles(threadId):获取指定线程的所有上传文件
  • deleteUploadedFile(threadId, filename):删除指定上传文件
  • getArtifactUrl(threadId, virtualPath):生成Artifact访问URL
  • ArtifactLink组件:自动渲染Artifact链接,支持在线预览和下载

DeerFlow 后端 LangGraph 实现全面分析

本文档提供了关于 LangGraph 如何作为 DeerFlow AI 代理系统核心执行运行时的完整分析。它涵盖了后端代码库中使用 LangGraph 的所有组件、架构模式、实现细节和部署模型。


DeerFlow 完全基于 LangGraph 作为其核心执行引擎构建,利用 LangGraph 在状态管理、检查点 (Checkpointing)、中间件支持和流式执行方面的原生能力,来交付生产级的 AI 代理平台。

核心执行流程遵循标准的 LangGraph 代理模式:

  1. 用户输入被添加到线程状态中
  2. 执行前中间件处理并丰富状态
  3. LLM 生成响应/工具调用
  4. 执行后中间件处理模型输出
  5. 如果请求了工具,则执行工具,并将结果添加到状态中
  6. 循环重复直到生成最终响应
  7. 在每个回合之间,通过 Checkpointer 持久化完整状态

文件: backend/packages/harness/deerflow/agents/thread_state.py

  • 扩展了 LangChain 标准的 AgentState (LangGraph 的默认代理状态 Schema),包含以下自定义字段:
    • sandbox: 隔离执行环境的引用
    • thread_data: 每线程的元数据,包括工作区路径
    • title: 自动生成的对话标题
    • artifacts: 代理生成的文件/输出
    • todos: 计划模式的任务跟踪列表
    • uploaded_files: 用户上传文件的引用
    • viewed_images: 供视觉模型使用的 Base64 编码的图像
  • 实现了自定义的 Reducer,用于在状态更新期间安全地合并 Artifact 和查看的图像

文件:

实现:

  • 可配置的 Checkpointer 工厂,支持 3 种持久化后端:
    1. InMemorySaver: 易失性的内存存储,用于测试/开发
    2. SqliteSaver: 基于文件的持久化存储,用于单实例部署
    3. PostgresSaver: 分布式的持久化存储,用于多实例生产部署
  • 提供单例和上下文管理器两种访问模式
  • 与 LangGraph 的 Checkpointing API 完全集成,实现在执行轮回之间自动持久化状态

所有中间件都实现了 LangGraph 的 BaseAgentMiddleware 接口,并在图 (Graph) 执行期间以严格预定义的顺序运行,从而在不修改核心图逻辑的情况下实现横切关注点 (cross-cutting functionality) 功能:

中间件文件路径目的
Thread Dataagents/middlewares/thread_data_middleware.py创建隔离的每线程目录 (workspace, uploads, outputs) 并将路径信息注入状态
Uploadsagents/middlewares/uploads_middleware.py跟踪用户上传的文件并将引用注入状态
Sandbox Lifecyclesandbox/middleware.py管理每个线程隔离执行沙盒的获取/释放
Dangling Tool Call Fixagents/middlewares/dangling_tool_call_middleware.py为缺少对应响应的中断的工具调用插入合成错误的 ToolMessages,防止 LLM 格式错误
Guardrailsguardrails/middleware.py针对配置的安全策略执行工具调用前的授权
Summarization(LangChain 內置中间件)可选的上下文摘要,在接近 Token 限制时触发,保留近期消息同时对旧消息进行摘要
Todo/Plan Modeagents/middlewares/todo_middleware.py通过 write_todos 工具实现用于任务跟踪的计划模式功能
Title Generationagents/middlewares/title_middleware.py在第一次完整轮次后自动生成对话标题
Memoryagents/middlewares/memory_middleware.py将对话轮次排队以进行异步的记忆提取和持久化
Image Viewagents/middlewares/view_image_middleware.py为支持视觉的模型将图像文件转换为 Base64
Deferred Tool Filteragents/middlewares/deferred_tool_filter_middleware.py过滤发送至 LLM 的延迟 MCP 工具 Schema(节省上下文 Token,工具可以在运行时通过 tool_search 发现)
Subagent Limitagents/middlewares/subagent_limit_middleware.py通过截断多出的并行任务调用来强制实行最大并发子代理限制
Tool Error Handlingagents/middlewares/tool_error_handling_middleware.py捕获工具执行错误并将其转换为 LLM 可处理的正确格式化的 ToolMessages
Token Usageagents/middlewares/token_usage_middleware.py跟踪图执行中跨所有 LLM 调用的 Token 消耗
Loop Detectionagents/middlewares/loop_detection_middleware.py检测并打破重复的工具调用循环
Clarificationagents/middlewares/clarification_middleware.py拦截 ask_clarification 工具调用并中断图的执行,以向用户返回澄清请求

文件:

实现:

  • make_lead_agent() 是主要的图入口点,并在 langgraph.json 中注册用于 LangGraph Server
  • 使用 LangChain 的 create_agent() 工具,该工具在内部构建带有标准代理节点(模型调用、工具执行、路由器)的 LangGraph StateGraph
  • 基于运行时配置动态地配置中间件、工具、LLM 模型和系统提示词
  • 在将其作为 Runnable 返回之前,使用配置好的 Checkpointer 编译生成该图

文件:

实现:

  • 子代理是在独立的线程池中运行的独立 LangGraph 代理
  • task 工具允许主代理将工作委托给子代理进行并行执行
  • 子代理执行器管理子代理任务的调度、执行和事件流处理
  • 每个子代理都有自己隔离的状态和执行流,并将结果反馈回通信给主代理

DeerFlow 支持 LangGraph 图的 3 种部署模型:

  1. 独立 LangGraph Server: 运行在 2024 端口,通过 HTTP API 访问 (在 langgraph.json 中配置)
  2. 嵌入式进程内: backend/packages/harness/deerflow/client.py 提供 DeerFlowClient,用于在进程内直接访问编译好的图而无需网络调用
  3. 频道集成 (Channel Integration): backend/app/channels/manager.py 使用 LangGraph SDK 与运行中的服务器交互,用于 IM 频道集成 (Slack/Feishu/Telegram)

  1. 动态图构建: 图在运行时通过可配置的组件 (中间件、工具、模型) 构建,而不是静态定义的
  2. 中间件优先的可扩展性: 所有横切功能都作为中间件实现,保持了核心图逻辑的清晰和易维护性
  3. 可插拔的持久化: Checkpointer 后端完全可配置而无需修改应用代码
  4. 层次化代理架构: 主代理将任务委派给子代理,每个子代理作为独立的 LangGraph 执行流运行
  5. 有状态执行: 完整的线程状态在轮次之间被持久化,从而实现了长时间运行的多轮对话和任务执行

所有与 LangGraph 相关的组件都有全面的单元测试:

DeerFlow 核心系统实现分析文档

本文档提供了对 DeerFlow 代理编排系统核心组件的全面技术分析,包括主代理 (Lead Agent) 架构、中间件管道、状态管理和记忆系统。该分析基于对代码库结构和实现模式的深入探索。


主代理是 DeerFlow 系统的中央编排者,作为一个基于 LangGraph 的代理实现,并支持动态配置。

核心文件: /backend/packages/harness/deerflow/agents/lead_agent/agent.py 入口点: make_lead_agent(config: RunnableConfig)

特性实现细节
动态模型解析基于配置自动选择合适的模型,并包含针对缺失模型的降级逻辑。模型优先级:请求参数 model_name > 自定义代理配置的模型 > 全局默认模型
自定义代理支持支持加载自定义代理配置(通过 agent_name 参数),具有独立的工具集、模型和记忆存储
思考模式支持解析模型能力,为支持的模型启用扩展的思考 (Thinking) 功能
计划模式集成在启用计划模式时,激活 TodoMiddleware 用于复杂的多步骤任务跟踪
子代理编排支持将任务委托给子代理,并可配置并发限制
引导模式 (Bootstrap Mode)提供用于自定义代理创建工作流的最小代理实例
动态工具加载基于模型能力、子代理启用状态和代理配置来加载工具

主代理通过严格排序的中间件链(详见第 2 节)在调用 LLM 前后执行请求,以确保所有交互处理的一致性。


所有中间件都继承自 AgentMiddleware 基类,并实现 before_agent() 和/或 after_agent() 钩子。它们在共享的 ThreadState 对象上运行,可以修改状态、中断执行或触发副作用。

执行顺序:

  • LLM 调用前: 中间件按定义的顺序运行,以在生成提示前对状态进行预处理
  • LLM 调用后: 中间件按相反的顺序运行,以在状态持久化前对响应进行后处理
  • 中断支持: 中间件可以返回 Command(goto=END) 来提前停止执行(例如用于请求澄清)

中间件按以下严格顺序执行。如果基于配置有条件加载,则标记为 [可选]

顺序中间件文件路径核心目的启用条件
1ThreadDataMiddleware/agents/middlewares/thread_data_middleware.py创建每线程的 workspace、uploads 和 outputs 目录,并将路径注入状态始终启用
2UploadsMiddleware/agents/middlewares/uploads_middleware.py跟踪新上传的文件并将其注入对话上下文始终启用
3SandboxMiddleware/sandbox/middleware.py获取执行沙盒实例并将 sandbox_id 存储在状态中始终启用
4DanglingToolCallMiddleware/agents/middlewares/dangling_tool_call_middleware.py为缺少对应结果的工具调用注入占位符响应始终启用
5GuardrailMiddleware/guardrails/middleware.py通过可插拔的 GuardrailProvider 协议提供工具调用前的授权[可选] 当配置中设置了 guardrails.enabled 时启用
6ToolErrorHandlingMiddleware/agents/middlewares/tool_error_handling_middleware.py将工具执行异常转换为格式化的 ToolMessages 供 LLM 处理始终启用
7SummarizationMiddlewareLangChain 內置当接近 Token 限制时执行自动上下文缩减[可选] 当配置中设置了 summarization.enabled 时启用
8TodoMiddleware/agents/middlewares/todo_middleware.py为计划模式实现在 write_todos 工具中的任务跟踪[可选] 当激活计划模式时启用
9TokenUsageMiddleware/agents/middlewares/token_usage_middleware.py跟踪和报告所有请求的 Token 消耗[可选] 当配置了 token_usage 跟踪时启用
10TitleMiddleware/agents/middlewares/title_middleware.py在第一次完整对话交流后自动生成描述性的线程标题始终启用
11MemoryMiddleware/agents/middlewares/memory_middleware.py将完成的对话排队以进行异步的长期记忆更新始终启用
12ViewImageMiddleware/agents/middlewares/view_image_middleware.py为支持视觉的模型将 base64 图像数据注入状态[可选] 仅当所选模型支持视觉能力时启用
13DeferredToolFilterMiddleware/agents/middlewares/deferred_tool_filter_middleware.py启用工具搜索时对模型隐藏延迟的工具 Schema[可选] 当配置了 tool_search 特性时启用
14SubagentLimitMiddleware/agents/middlewares/subagent_limit_middleware.py通过截断多余的并行任务调用来强制执行最大并发子代理限制[可选] 当开启子代理特性时启用
15LoopDetectionMiddleware/agents/middlewares/loop_detection_middleware.py检测并阻断重复的工具调用循环,以防止无限执行始终启用
16ClarificationMiddleware/agents/middlewares/clarification_middleware.py拦截 ask_clarification 工具调用并中断执行以请求用户输入始终启用(必须是链中的最后一个中间件)

系统使用扩展的 LangChain AgentState 来存储所有与对话相关的数据。

核心文件: /backend/packages/harness/deerflow/agents/thread_state.py

class ThreadState(AgentState):
sandbox: NotRequired[SandboxState] # 执行沙盒标识符 (可选字段)
thread_data: NotRequired[ThreadDataState] # Workspace/uploads/outputs 路径 (可选字段)
title: NotRequired[str] # 自动生成的线程标题 (可选字段)
artifacts: Annotated[list[str], merge_artifacts] # 生成的输出文件
todos: NotRequired[list] # 计划模式的任务列表 (可选字段)
uploaded_files: NotRequired[list[dict]] # 当前会话中上传的文件 (可选字段)
viewed_images: Annotated[dict[str, ViewedImageData], merge_viewed_images] # 缓存的图像数据
  • merge_artifacts: 合并和去重 Artifact,同时保持顺序
  • merge_viewed_images: 合并图像字典,支持通过空字典清理缓存

Checkpointer 系统为对话状态提供持久化存储,支持多种后端选项。

核心文件:

  • 同步 Provider: /backend/packages/harness/deerflow/agents/checkpointer/provider.py
  • 异步 Provider: /backend/packages/harness/deerflow/agents/checkpointer/async_provider.py
后端使用场景
In-Memory用于测试/开发的默认选项,非持久化
SQLite用于单节点部署的基于文件的持久化
PostgreSQL用于多节点生产部署的分布式持久化
  • 单例模式用于同步使用 (跨调用复用,在进程退出时关闭)
  • 上下文管理器模式用于具有确定性清理的一次性操作
  • 首次使用时自动设置数据库 Schema
  • 通过 config.yamlcheckpointer 部分进行配置
  • 当没有配置持久化 Checkpointer 时自动降级到 InMemorySaver

记忆系统实现了双层架构:

  1. 短期记忆: 由 Checkpointer 系统管理,存储完整的对话状态
  2. 长期记忆: 对用户上下文、事实和历史信息的持久化存储

核心文件: /backend/packages/harness/deerflow/agents/memory/storage.py

  • 抽象接口: MemoryStorage 为存储提供商定义了标准接口
  • 默认实现: FileMemoryStorage 将记忆作为 JSON 文件存储在磁盘上
  • 可插拔架构: 通过配置支持自定义存储提供商
  • 缓存: 带文件修改时间检查的内存缓存,以保证数据新鲜度
  • 原子写入: 使用 临时文件 + 重命名 模式来防止数据损坏
  • 多租户支持: 为自定义代理提供分离的记忆存储
{
"version": "1.0",
"lastUpdated": "ISO 8601 时间戳",
"user": {
"workContext": {"summary": "", "updatedAt": ""},
"personalContext": {"summary": "", "updatedAt": ""},
"topOfMind": {"summary": "", "updatedAt": ""}
},
"history": {
"recentMonths": {"summary": "", "updatedAt": ""},
"earlierContext": {"summary": "", "updatedAt": ""},
"longTermBackground": {"summary": "", "updatedAt": ""}
},
"facts": [
{
"id": "fact_xxxx",
"content": "事实内容",
"category": "preference/knowledge/context/behavior/goal",
"confidence": 0.0-1.0,
"createdAt": "",
"source": "thread_id"
}
]
}

核心文件: /backend/packages/harness/deerflow/agents/memory/updater.py

  • 使用 LLM 从对话上下文中提取有意义的更新
  • 更新用户上下文部分 (work, personal, top of mind)
  • 更新历史上下文部分 (recent months, earlier, long term)
  • 提取具有置信度分数的离散事实
  • 基于标准化内容对事实进行去重
  • 实施最大事实数限制(保留置信度最高的事实)
  • 自动剥离文件上传相关的提及,以避免过期的引用
  • 执行原子更新以防止记忆损坏

核心文件: /backend/packages/harness/deerflow/agents/memory/queue.py

  • 防抖更新队列,以避免频繁的 LLM 调用
  • 在可配置的窗口(默认:30秒)内批处理多个对话更新
  • 线程去重:每个线程只保留最新的对话
  • 后台线程处理,以避免阻塞代理执行
  • 通过 flush() 方法支持优雅关机

核心文件: /backend/packages/harness/deerflow/agents/middlewares/memory_middleware.py

  • 在代理执行后运行,将对话排队以进行记忆更新
  • 过滤消息,仅保留用户输入和最终的助手响应
  • 从记忆中移除中间工具调用/结果
  • 从用户消息中剥离临时的上传块
  • 跳过仅有上传而没有真正用户文本的轮次
  • 仅将至少包含一条用户消息和一条助手消息的对话排队

  1. 请求入口: 用户请求进入系统并被包装在 ThreadState 中
  2. 中间件链构建: 主代理基于配置动态构建中间件链,仅包含启用的可选中间件
  3. 中间件预处理: 中间件按定义的顺序运行,以在生成提示前对状态进行预处理
  4. 主代理执行: LLM 处理准备好的状态并生成响应/工具调用
  5. 工具执行: 如果生成了工具调用,ToolErrorHandlingMiddleware 会带有错误处理地执行它们
  6. 中间件后处理: 中间件按相反顺序运行,以在状态持久化之前处理响应
  7. 状态持久化: 更新后的 ThreadState 被保存到 Checkpointer 中
  8. 记忆更新: 完成的对话被排队进行异步长期记忆更新
组件交互描述
主代理 ↔ 中间件主代理在初始化期间构建中间件链,基于配置动态地仅包含启用的可选中间件
中间件 ↔ 状态管理所有中间件从共享的 ThreadState 对象读取并进行修改
ToolErrorHandlingMiddleware ↔ 工具执行捕获工具执行异常并将其转换为格式化的 ToolMessages 供 LLM 处理,避免执行中断
记忆中间件 ↔ 记忆系统MemoryMiddleware 将过滤后的对话排队到 MemoryUpdateQueue 中进行异步处理
Checkpointer ↔ 线程状态Checkpointer 会在每个执行步骤后自动持久化完整的 ThreadState
主代理 ↔ 子代理主代理使用子代理工具委托任务,并通过 SubagentLimitMiddleware 强制实施并发限制

所有组件都遵循严格的依赖注入模式,并且完全可以通过中心的 config.yaml 文件进行配置,而无需修改代码。

DeerFlow Harness 架构分析

Harness 是 DeerFlow 的核心代理框架层,以独立 Python 包 deerflow-harness 的形式发布,是整个系统的”引擎”部分,封装了所有构建、运行 AI 代理所需的核心能力,上层应用(Gateway、Channels 等)基于 Harness 提供的能力进行业务开发。

  1. 可复用性:作为独立包可被其他项目直接引用,快速搭建 AI 代理系统,避免重复造轮子
  2. 可扩展性:高度模块化设计,所有核心组件都支持自定义扩展,适应不同业务场景需求
  3. 边界清晰:与上层应用严格解耦,Harness 不依赖上层应用代码,保证框架的通用性
  4. 生产级:内置线程安全、资源管理、错误处理、监控告警等生产级特性,支持高并发场景
  5. 易用性:提供简洁的 API 接口,屏蔽底层复杂实现,降低 AI 代理开发门槛

Harness 采用模块化架构,核心分为以下几层:

┌─────────────────────────────────────────────────────────┐
│ Client API │
│ (DeerFlowClient: 嵌入式调用接口,与 Gateway API 兼容) │
├─────────────────────────────────────────────────────────┤
│ Agent Layer │
│ Lead Agent / Middleware Chain / Thread State / Memory │
├─────────────────────────────────────────────────────────┤
│ Core Capability Layer │
│ Tools / MCP / Skills / Subagents / Sandbox / Models │
├─────────────────────────────────────────────────────────┤
│ Foundation Layer │
│ Config / Reflection / Guardrails / Tracing / Utils │
└─────────────────────────────────────────────────────────┘
  • 统一配置加载:支持 config.yamlextensions_config.json 两种配置文件
  • 环境变量解析:自动解析配置中的 $ENV_VAR 格式的环境变量引用
  • 热重载:配置文件修改自动检测重载,无需重启服务
  • 配置验证:Pydantic 模型校验配置格式正确性
  • 包含子配置:AppConfig、ModelConfig、SandboxConfig、SkillsConfig、MemoryConfig 等
  • 动态类加载:通过字符串路径(如 module.path:ClassName)动态加载类和实例
  • 类型校验:加载时自动校验类是否继承自预期的基类
  • 错误友好:缺失依赖时返回可执行的安装提示
  • 插件化护栏:支持自定义 GuardrailProvider 实现工具调用鉴权
  • 内置实现:AllowlistProvider 基于白名单的工具访问控制
  • 中间件集成:在工具调用前自动执行护栏检查,拒绝非法操作

2. 核心能力层 (Core Capability Layer)

Section titled “2. 核心能力层 (Core Capability Layer)”
  • 抽象接口:SandboxSandboxProvider 接口定义
  • 多实现支持:本地文件系统模式、Docker 容器模式、远程 K8s 模式
  • 路径映射:虚拟路径到物理路径的自动转换,对 Agent 透明
  • 工具封装:bash/read_file/write_file/ls/str_replace 等沙箱工具
  • 模型工厂:create_chat_model() 统一创建不同厂商的 LLM 实例
  • 多厂商支持:Anthropic、OpenAI、DeepSeek、Minimax、Google 等
  • 扩展特性:支持思考模式、视觉能力、响应式 API 等
  • 凭证管理:自动加载环境变量中的 API Key
  • 内置工具:present_files/ask_clarification/view_image
  • MCP 集成:自动加载 MCP 服务器提供的工具,支持 SSE/HTTP/stdio 传输
  • 社区工具:Tavily 搜索、Firecrawl 爬虫、Jina AI 阅读、DuckDuckGo 搜索等
  • 工具分组:支持按组加载工具,灵活配置 Agent 可用能力
  • 技能发现:自动扫描 skills/ 目录下的技能
  • 技能解析:解析 SKILL.md 中的元数据(名称、描述、权限等)
  • 技能注入:自动将启用的技能注入到 Agent 系统提示中
  • 技能安装:支持通过 API 上传安装 .skill 格式的技能包
  • 内置代理:general-purpose(通用代理)、bash(命令执行专家)
  • 并发控制:默认最大 3 个并发子代理,避免资源耗尽
  • 异步执行:后台线程池执行子代理任务,不阻塞主流程
  • 事件通知:通过 SSE 推送子代理执行状态(开始/运行中/完成/失败)
  • 多服务器管理:同时连接多个 MCP 服务器
  • 懒加载:工具首次使用时才初始化,节省启动时间
  • 缓存失效:配置文件修改自动重新加载 MCP 工具
  • OAuth 支持:自动刷新令牌,注入 Authorization 头
  • 入口函数:make_lead_agent() 创建代理实例
  • 动态工具加载:根据配置自动组合沙箱、内置、MCP、社区、子代理工具
  • 系统提示生成:动态注入技能、内存、子代理等相关的系统提示
  • 基于 LangGraph:使用 LangGraph 作为工作流引擎

按执行顺序排列:

  1. ThreadDataMiddleware:创建线程专属目录结构
  2. UploadsMiddleware:处理上传文件,注入到会话中
  3. SandboxMiddleware:获取/释放沙箱实例
  4. DanglingToolCallMiddleware:处理中断的工具调用
  5. GuardrailMiddleware:工具调用鉴权
  6. SummarizationMiddleware:接近 Token 限制时自动会话摘要
  7. TodoMiddleware:计划模式下的任务列表管理
  8. TitleMiddleware:自动生成会话标题
  9. MemoryMiddleware:异步更新记忆系统
  10. ViewImageMiddleware:图像数据注入,支持视觉模型
  11. SubagentLimitMiddleware:子代理并发数限制
  12. ClarificationMiddleware:拦截澄清请求,中断执行
  • ThreadState:会话状态 Schema,包含沙箱、线程数据、标题、 artifacts、任务列表、上传文件、查看过的图片等
  • 自定义 Reducer:实现状态合并逻辑,避免重复数据
  • Checkpoint:支持 SQLite 等持久化 Checkpoint 存储
  • 事实提取:自动从对话中提取用户偏好、知识、目标等事实
  • 去重逻辑:自动检测重复事实,避免冗余存储
  • 延迟更新:队列批量处理更新,减少 LLM 调用次数
  • 上下文注入:会话开始时自动注入相关记忆到系统提示
  • DeerFlowClient:嵌入式 Python 客户端,无需启动 HTTP 服务即可使用所有能力
  • API 兼容:返回格式与 Gateway API 完全一致,上层代码无需修改即可在 HTTP 和嵌入式模式下切换
  • 流式支持:支持对话流式输出,与 LangGraph SSE 协议对齐

✅ 所有代理运行相关的核心逻辑 ✅ Agent、工具、沙箱、模型、技能、子代理、MCP 等核心组件 ✅ 配置、反射、护栏等基础能力 ✅ 嵌入式客户端 API

❌ FastAPI Gateway 接口层 ❌ IM 通道(Feishu/Slack/Telegram)集成 ❌ 前端页面 ❌ 具体业务逻辑

允许:App → Harness(上层应用调用 Harness 接口) 禁止:Harness → App(Harness 不能依赖上层应用代码) 该规则由 tests/test_harness_boundary.py 单测强制保障

Harness 提供了丰富的扩展点,支持按需定制:

  1. 自定义模型:实现模型 Provider,接入新的 LLM 厂商
  2. 自定义工具:开发新的工具类,扩展 Agent 能力
  3. 自定义沙箱:实现 SandboxProvider,支持新的隔离技术
  4. 自定义护栏:实现 GuardrailProvider,自定义工具访问控制逻辑
  5. 自定义中间件:添加新的中间件,扩展 Agent 处理流程
  6. 自定义技能:开发新的技能包,复用特定领域能力
  1. LangGraph 作为工作流引擎

    • 原生支持状态管理、工具调用、多轮对话等 Agent 核心能力
    • 内置 Checkpoint 机制,支持会话中断恢复
    • 流式输出、事件驱动架构,适合构建交互型 Agent
    • 生态丰富,与 LangChain 工具链无缝集成
  2. Pydantic 作为配置与数据结构基础

    • 类型安全,自动校验,减少运行时错误
    • 序列化/反序列化友好,方便 API 交互
    • 自动生成 OpenAPI 文档,降低集成成本
  3. 模块化依赖设计

    • 可选依赖:社区工具、特定厂商 SDK 等作为可选依赖,用户可以按需安装
    • 核心轻量:核心框架依赖少,启动速度快,部署方便
  1. 多层安全隔离

    • 沙箱层:Docker/K8s 容器级隔离,防止 Agent 操作影响宿主系统
    • 路径映射层:虚拟路径到物理路径的转换,防止目录遍历攻击
    • 护栏层:工具调用鉴权,禁止访问敏感资源
    • 输入输出过滤:命令执行前后自动处理路径,防止泄露内部路径信息
  2. 最小权限原则

    • 技能目录只读挂载,防止 Agent 修改系统技能
    • ACP 工作区只读挂载,Agent 只能读取执行结果
    • 沙箱容器默认以非 root 用户运行,减少攻击面
  1. 懒加载机制

    • MCP 工具首次使用时才初始化,减少启动时间
    • 模型实例按需创建,避免预加载不必要的模型
    • 技能配置懒加载,提高响应速度
  2. 缓存策略

    • MCP 工具缓存,配置文件修改才重新加载
    • 沙箱暖池机制,避免容器冷启动开销
    • 记忆系统批量更新,减少 LLM 调用次数
  3. 并发控制

    • 子代理并发数限制,防止资源耗尽
    • 沙箱副本数限制,避免容器过多占用系统资源
    • 线程池大小合理配置,平衡并发能力与资源消耗
  1. Token 使用统计:内置 Token 用量统计中间件,精确计算每轮对话的 Token 消耗
  2. Tracing 支持:集成 OpenTelemetry,支持全链路追踪
  3. 结构化日志:所有核心组件都有完善的日志输出,方便问题排查
  4. 监控指标:内置关键指标采集,方便对接 Prometheus/Grafana 监控体系
  • 单元测试覆盖率超过 80%,核心模块覆盖率 100%
  • 边界测试:覆盖异常场景、错误输入、并发冲突等
  • 集成测试:验证与第三方服务(LLM、MCP、沙箱等)的集成兼容性
  • 压力测试:验证高并发场景下的稳定性和性能表现
  • 独立发布为 Python 包 deerflow-harness,版本遵循 SemVer 规范
  • 其他项目可以通过 pip install deerflow-harness 直接安装使用
  • 提供完整的文档和示例代码,降低使用门槛
  • 内置完整的单元测试,保证包的质量和稳定性
  1. 双模式部署支持:同时支持嵌入式部署(直接调用 Python API)和 HTTP 服务部署(Gateway + LangGraph Server),同一套代码适配不同场景
  2. API 一致性设计:嵌入式客户端与 Gateway API 返回格式完全一致,上层应用无缝切换部署模式
  3. 插件化生态:通过 MCP、技能、自定义扩展点,形成开放的插件生态,能力可以无限扩展
  4. 跨环境兼容:支持本地开发、Docker 部署、K8s 部署等多种环境,配置自动适配
  1. 多语言支持:目前核心是 Python 实现,未来可以考虑支持多语言 SDK
  2. 分布式调度:当前沙箱和子代理执行是单机模式,未来可以扩展为分布式调度,支持大规模部署
  3. 更丰富的扩展点:增加更多的钩子函数,允许更灵活的自定义 Agent 行为
  4. 可视化编排:提供可视化界面编排 Agent 工作流,降低使用门槛
  1. 构建 AI 助理应用:快速搭建通用 AI 助理,支持工具调用、代码执行、文件处理等能力
  2. 企业内部 Agent 平台:基于 Harness 定制企业专属的 Agent 系统,集成内部业务系统和数据
  3. AI 研发平台:作为 Agent 运行时,支撑上层的低代码 Agent 开发平台,让非专业人员也能构建 Agent
  4. 自动化工作流:构建复杂的自动化任务流,替代人工执行重复性高、规则明确的工作
  5. 教育与研究:作为 AI Agent 研究的实验平台,快速验证新的 Agent 架构和算法

DeerFlow 配置系统实现说明

DeerFlow采用双文件、模块化的配置系统设计,将核心应用配置与扩展配置分离,同时支持环境变量注入、自动热重载、版本校验等企业级特性,兼顾灵活性与易用性。


DeerFlow配置系统由两个独立的配置文件组成:

配置文件格式存储内容位置
config.yamlYAML应用核心配置(模型、沙箱、工具、内存、子Agent等)项目根目录
extensions_config.jsonJSON扩展配置(MCP服务器、技能开关状态)项目根目录
  • 核心配置稳定config.yaml包含系统运行必需的基础配置,变更频率低
  • 扩展配置灵活extensions_config.json包含动态变化的扩展配置,支持运行时修改
  • 敏感信息分离:所有敏感信息通过环境变量注入,不硬编码在配置文件中
  • 热重载支持:配置文件修改后自动生效,无需重启服务

配置文件路径按以下优先级解析:

  1. 显式传入的config_path参数
  2. DEER_FLOW_CONFIG_PATH环境变量
  3. 当前工作目录下的config.yaml
  4. 当前工作目录父目录下的config.yaml(推荐位置)
  1. 显式传入的config_path参数
  2. DEER_FLOW_EXTENSIONS_CONFIG_PATH环境变量
  3. 当前工作目录下的extensions_config.json
  4. 当前工作目录父目录下的extensions_config.json(推荐位置)
  5. 兼容旧版:查找mcp_config.json作为备选
  6. 不存在则返回空配置(扩展功能可选)

配置系统支持递归解析以$开头的环境变量引用:

  • 示例:api_key: $OPENAI_API_KEY会自动替换为对应环境变量的值
  • 作用范围:主配置和扩展配置中的所有字符串值都支持环境变量解析
  • 错误处理:环境变量不存在时主配置会抛出异常,扩展配置会替换为空字符串避免运行错误

加载主配置时会自动对比用户配置与config.example.yaml的版本:

  • 配置文件中config_version字段标识版本号
  • 缺失config_version视为版本0
  • 用户版本低于示例版本时会输出警告,提示运行make config-upgrade升级配置

主配置加载时会按功能模块分别初始化全局单例配置:

  • title:自动标题生成配置
  • summarization:上下文摘要配置
  • memory:记忆系统配置
  • subagents:子Agent配置
  • tool_search:工具搜索配置
  • guardrails:安全护栏配置
  • checkpointer:状态持久化配置
  • acp_agents:ACP外部Agent配置
  • 扩展配置独立加载后合并到主配置的extensions字段

配置系统内置自动热重载能力:

  • 首次加载后缓存配置单例和文件修改时间(mtime)
  • 每次调用get_app_config()时检查文件修改时间
  • 检测到文件变更时自动重新加载配置,无需重启服务
  • 扩展配置目前需手动调用reload_extensions_config()重载

基于Pydantic实现的强类型配置结构:

class AppConfig(BaseModel):
log_level: str # 日志级别
token_usage: TokenUsageConfig # Token用量跟踪配置
models: list[ModelConfig] # 可用LLM模型列表
sandbox: SandboxConfig # 沙箱执行环境配置
tools: list[ToolConfig] # 自定义工具配置
tool_groups: list[ToolGroupConfig] # 工具分组配置
skills: SkillsConfig # 技能系统配置
extensions: ExtensionsConfig # 扩展配置(自动加载)
tool_search: ToolSearchConfig # 工具搜索配置
checkpointer: CheckpointerConfig | None # 状态持久化配置

每个功能领域都有独立的配置类:

配置类功能
ModelConfigLLM模型配置(提供商、密钥、参数、能力标识等)
SandboxConfig沙箱环境配置(提供商、路径映射、资源限制等)
ToolConfig自定义工具配置(加载路径、参数等)
MemoryConfig记忆系统配置(开关、存储路径、模型、阈值等)
SubagentsConfig子Agent配置(开关、超时时间等)
SummarizationConfig摘要配置(开关、触发条件、模型等)
GuardrailsConfig安全护栏配置(开关、提供商、规则等)
class ExtensionsConfig(BaseModel):
mcp_servers: dict[str, McpServerConfig] # MCP服务器配置
skills: dict[str, SkillStateConfig] # 技能开关状态配置

MCP服务器配置支持三种传输方式:

Section titled “MCP服务器配置支持三种传输方式:”
  1. stdio:本地子进程方式启动MCP服务器
  2. sse:连接远程SSE协议的MCP服务器
  3. http:连接远程HTTP协议的MCP服务器
  • 支持OAuth2认证(client_credentials/refresh_token模式)
  • 支持自定义环境变量和HTTP头

  • 主配置文件修改后自动生效,无需重启LangGraph或Gateway服务
  • 基于文件修改时间检测变更,性能开销可忽略
  • 运行中的会话自动使用新配置,无需中断用户交互
  • 所有敏感信息(API密钥、令牌等)都可以通过环境变量传递
  • 配置文件中仅保留环境变量引用,避免密钥泄露
  • 支持递归解析嵌套结构中的环境变量
  • 自动检测过时的配置文件,提示用户升级
  • 配套make config-upgrade命令自动合并新配置字段
  • 向后兼容旧版本配置,避免升级故障
  • 所有配置都基于Pydantic模型定义,加载时自动校验类型
  • 格式错误提前发现,避免运行时异常
  • 支持IDE自动补全和类型提示
  • 按功能领域拆分配置模块,易于扩展和维护
  • 新增功能配置无需修改核心配置加载逻辑
  • 每个子配置模块有独立的加载和访问API
  • 通过环境变量指定配置文件路径,支持开发、测试、生产等多环境部署
  • 配置文件可以独立于代码仓库管理,避免敏感信息提交

除了静态配置文件,DeerFlow还支持在会话级别动态配置功能开关:

配置参数作用默认值
is_plan_mode开启/关闭Plan Mode任务跟踪功能False
model_name指定当前会话使用的LLM模型配置文件中第一个模型
thinking_enabled开启/关闭模型思考模式True
subagent_enabled开启/关闭子Agent委派功能False
max_concurrent_subagents最大并发子Agent数3
reasoning_effort推理努力程度(low/medium/high)None

运行时配置通过config.configurable参数在创建Agent会话时传入,仅对当前会话生效。


# 获取主配置单例(自动热重载)
from deerflow.config import get_app_config
config = get_app_config()
# 获取扩展配置单例
from deerflow.config import get_extensions_config
ext_config = get_extensions_config()
# 强制重载主配置
from deerflow.config import reload_app_config
new_config = reload_app_config()
# 强制重载扩展配置
from deerflow.config import reload_extensions_config
new_ext_config = reload_extensions_config()
# 重置配置缓存(测试用)
from deerflow.config import reset_app_config, reset_extensions_config
reset_app_config()
# 注入自定义配置(测试用)
from deerflow.config import set_app_config, AppConfig
custom_config = AppConfig(...)
set_app_config(custom_config)
# 获取指定模型配置
model_config = get_app_config().get_model_config("claude-3-opus")
# 获取指定工具配置
tool_config = get_app_config().get_tool_config("bash")
# 获取启用的MCP服务器
enabled_mcp = get_extensions_config().get_enabled_mcp_servers()
# 检查技能是否启用
is_enabled = get_extensions_config().is_skill_enabled("commit", "public")

  1. 敏感信息管理:所有API密钥、凭证都通过环境变量传递,不要硬编码在配置文件中
  2. 配置版本控制config.example.yaml提交到代码仓库,实际config.yaml加入.gitignore
  3. 热重载使用:修改配置文件后等待几秒自动生效,无需重启服务
  4. 多环境部署:通过DEER_FLOW_CONFIG_PATH环境变量指定不同环境的配置文件
  5. 配置升级:当看到版本过时警告时,运行make config-upgrade自动合并新字段

DeerFlow Backend Sandbox 执行环境分析

本文档分析了在 deer-flow 后端体系中,代码沙箱执行环境(Sandbox)的架构设计与实现原理。沙箱主要用于让 AI 或用户安全、隔离地执行代码块(Shell 命令、读写文件等)。

后端的沙箱系统被设计为一个标准的面向对象接口体系,具有极高的解耦和可替换性:

定义在 packages/harness/deerflow/sandbox/sandbox.py。 它是一个标准的接口层,规定了所有沙箱必须提供以下能力:

  • execute_command(command):执行终端命令。
  • read_file(path) / write_file(path, content) / update_file:文本与二进制文件的 I/O 操作。
  • list_dir(path, max_depth):目录遍历。

1.2 SandboxProvider (生命周期、路由与缓存引擎)

Section titled “1.2 SandboxProvider (生命周期、路由与缓存引擎)”

定义在 sandbox_provider.py,但在 aio_sandbox_provider.py 中有极其高级的实现。 它是单例管理器,负责沙箱生命周期的调度:

  • acquire:获取或新建一个特定线程的沙箱空间。在 AIO Provider 中,它实现了一个极致的三层缓存架构
    • 第一层 (In-process cache):极速复用当前进程已挂载的活跃沙箱。
    • 第二层 (Warm pool):将释放的沙箱置于“保暖池”(容器不销毁,只解除绑定),以便同一个 Thread 再次申请时“零冷启动”秒速复用。
    • 第三层 (Cross-process Discovery):通过确定性哈希 ID(Deterministic ID)和跨进程文件锁(File Lock),让不同进程甚至不同 Pod 能够发现彼此启动的共享底层沙箱,解决多进程冲突。
  • get:根据 ID 提取已挂载的沙箱实例并在后台自动续签闲置过期时间 (Idle Timeout)。
  • release:将闲置沙箱退回到保暖池,只有超过系统限定副本数(Replicas)或超时时才会真正执行销毁任务。

2. 具体实现机制 (Concrete Implementations)

Section titled “2. 具体实现机制 (Concrete Implementations)”

目前系统中存在两种截然不同的沙箱实现策略:

2.1 本地宿主机伪沙箱 (LocalSandbox)

Section titled “2.1 本地宿主机伪沙箱 (LocalSandbox)”

定义在 sandbox/local/local_sandbox.py。 这是一种非容器化的轻量级实现形式,直接在后端进程宿主机通过原生进程执行命令。

  • 执行原理:底层使用了 Python 原生的 subprocess.run(command, shell=True) 来直接执行 Bash/Zsh 脚本,这代表着它并没有真正的物理隔离,执行的是宿主机的直接命令。
  • 智能路径映射机制(Path Mapping):为了让从外部或者习惯了容器化路径的工具能够平滑运行,它包含了一个精妙的正则拦截系统。
    • 它在内存里维护了一套映射表(如把虚拟容器路径 /mnt/skills 映射到真实的宿主物理路径 /Users/...)。
    • 在把用户的命令喂给 subprocess.run 执行之前,它会先通过正则,把命令里出现的虚拟路径全部**替换(Resolve)**成真实的绝对路径。
    • 当真实命令吐出 Output 日志时,它又会把这些真实的、可能泄漏隐私的绝对物理路径,全部**反向替换(Reverse Resolve)**回虚拟容器路径。实现了对大模型视角下的“路径伪装隔离”。

2.2 容器化云原生沙箱 (AioSandboxSandboxBackend)

Section titled “2.2 容器化云原生沙箱 (AioSandbox 与 SandboxBackend)”

定义在社区模块 community/aio_sandbox/ 下。这是一套真正的物理级别的容器化隔离方案,被拆分为执行者(AioSandbox)和驱动引擎(SandboxBackend)两个维度:

  • 执行器 (AioSandbox) 通信隔离:所有的 execute_command 并不是本地 Subprocess,而是被转化为长超时的 HTTP REST API,发送给内部运行了 agent-infra/sandbox 服务的 Docker 容器。
  • 底层驱动引擎 (SandboxBackend):负责产生并调度这些隔离容器。它支持两种模式:
    • RemoteSandboxBackend:连接远程 K8s / K3s 的 Provisioner,动态生成远端 Pod。
    • LocalContainerBackend:直接按需在物理机上启动新的 Docker 容器,并分配闲置端口。特别地,在 macOS 系统下,它会优先检测并采用苹果官方原生支持的轻量级虚拟化方案 (Apple Container),仅在找不到时降级回退给 Docker。此设计极大优化了 Mac 上的 I/O 与执行速度。
    • 请求将指令发往由 agent-infra/sandbox 提供的一个运行在大后方的 Docker 容器内部服务(默认为 HTTP API 监听)。
    • 由该远程 Docker 容器内部安全地执行这些指令代码,并将结果 JSON(通常包含 result.data.output)返回给后端的 AioSandbox 包装实例。

通过这套抽象实现,当 AI 大模型提出如 在命令行执行 python script.py 的需求时:

  • 系统不需重构大模型逻辑,即可通过配置自由决定是采用零成本的本地直连替换(LocalSandbox),还是高规格的容器 HTTP 远程直连(AioSandbox)。
  • 两套底层驱动均共享同一个上层执行接口,达到了业务代码的高度复用。

DeerFlow Backend 架构分析:记忆、工具与技能系统

本文档分析了 deer-flow 后端(基于 LangGraph 开发,主要代码位于 packages/harness/deerflow 下)的核心三大系统实现机制。

记忆系统被精心设计为“短期(会话)”与“长期(全局)”两个层级:

1.1 短期记忆(基于 Thread Checkpointer)

Section titled “1.1 短期记忆(基于 Thread Checkpointer)”

通过 LangGraph 原生支持的 checkpointer/async_provider.py,记录特定对话流(Thread ID)的每一次状态流转(状态机快照)。这意味着用户刷新页面或断开连接后,对话上下文依然完整保留且可追溯。

1.2 长期异步记忆(全局档案提取)

Section titled “1.2 长期异步记忆(全局档案提取)”

核心分布在 agents/memory/storage.pyagents/middlewares/memory_middleware.py

  • 无感更新(中间件拦截)MemoryMiddleware 会拦截所有对话记录。为了节省 Token 并消除噪音,它会精准过滤掉内部大模型思考链和工具调用的中间过程记录,只保留纯人类提问和 AI 最终回复。
  • 队列防抖处理:整理后的“干净”对话记录会被推入 queue.py 的内存防抖队列中。这种设计有效防止了高频、高并发聊天引发的后端计算风暴。
  • 结构化档案与 LLM 提取:后台异步消费队列,调用 LLM 进行记忆提取,将其存储为持久化的结构化 JSON 档案(保存在本地配置路径内)。保存的档案节点非常精细,包括:
    • workContext:工作上下文
    • personalContext:个人偏好习惯
    • topOfMind:近期关注重点(脑海优先区域)
    • history:包含 recentMonthsearlierContext 等长期和近期时间线归纳
    • facts:用户相关的客观事实规律摘要

这种设计使得 Agent 具备了跨越时间和窗口了解用户的能力。


工具系统具有极高的模块化和扩展性,主要分布在 tools/community/ 等目录下:

位于 tools/builtins 目录。这些通常是需要最快响应速度、最底层依赖的基础计算工具等。

高度隔离的第三方服务接入层:

  • 多模态搜索:集成了 ddg_search (DuckDuckGo)、tavily 高级搜索引擎以及 image_search 图片搜索。
  • 安全沙箱执行环境:如 aio_sandbox,允许大模型生成的代码在一个隔离安全的环境(可能支持了本地或远程后端)中真机运行。
  • 文档读取工具:诸如读取复杂网页的 firecrawl 爬虫工具等。

2.3 MCP (Model Context Protocol) 扩展协议

Section titled “2.3 MCP (Model Context Protocol) 扩展协议”

目录结构涵盖 mcp/ 和配置文件 config/acp_config.py,标志着应用引入了工业界最新的大模型上下文通信标准协议(MCP)。这使得该后端可以在未来轻松地“挂载”诸如本地数据库读取器、VS Code 本地环境探针等强大的动态独立工具,彻底解耦代码。


通过分析 skills/ 目录下的组成部分(loader.py, parser.py, installer.py, validation.py, types.py),可以发现“技能(Skills)”和传统的 Python 代码“工具(Tools)”在架构地位上存在本质差异:

技能是一种软编码(Soft-coded)的注入型操作规范(SOP)或声明式模板,而非特定的 Python 执行逻辑。根据 parser.py 的源码实现,技能具有及其严格的物理约束:

  • 文件名必须严格为:SKILL.md
  • 文件头部必须包含标准的 YAML 前置元数据(Front-matter,需包含 namedescription),用于大模型技能发现。
  • 解析(Parser):运行时热解析特定格式的外部文件资源。
  • 静态校验(Validation):由于技能文件具备特定类型(见 types.py),系统会在挂载前通过 Schema 校验其参数与输入输出定义的合法性。
  • 注册安装(Installer & Loader):经验证后的技能会被挂载进大模型(Lead Agent 等)的 Prompts 集合或能力感知池中。

这种极致设计意味着,在不需要后端工程师改动或部署一行 Python 业务代码的情况下,仅通过上传、配置新的技能文件库,就可以瞬间赋能 AI 掌握全新的办事规范(比如:“如何审查 React 代码的规范”或“提交 PR 的标准格式”)。