Skip to content

博客

文件上传与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自动合并新字段