跳转到内容

Deer-Flow 的 Harness/App 分层架构

Deer-Flow 的 Harness/App 分层架构

学习目标

  • 理解 Deer-Flow 后端的两层拆分及其依赖方向
  • 掌握导入防火墙的 CI 强制执行机制
  • 学会分析分层架构对可嵌入性的影响

项目实践

两层拆分

Deer-Flow 的后端拆分为两个层次,依赖方向严格单向:

包名导入前缀可发布性
Harnessdeerflow-harnessdeerflow.*可发布为 PyPI 包
App未发布app.*内部使用

导入防火墙

tests/test_harness_boundary.py 在 CI 中强制执行导入方向检查:

  • 扫描 packages/harness/deerflow/ 下的所有 Python 文件
  • 检测是否存在 from app.*import app 语句
  • 发现违规 → CI 失败

效果:Harness 层可以独立作为 Python 库使用,不依赖 App 层的 FastAPI 或 IM 渠道代码。

为什么这样拆分

背景:Deer-Flow 的嵌入式 Python 客户端(DeerFlowClient)需要直接使用 Harness 层的能力,不经过 HTTP Gateway。

拆分的好处

  • DeerFlowClient 仅导入 Harness,不引入 FastAPI 等 Web 依赖
  • Harness 可独立发布为 deerflow-harness PyPI 包
  • App 层可以替换(如用 gRPC 替代 FastAPI)而不影响 Harness

问题与规避

循环导入

Harness 和 App 之间如果存在双向依赖,可能导致循环导入。

规避test_harness_boundary.py 在 CI 中拦截违规导入。开发时使用 PYTHONPATH=. uv run pytest tests/test_harness_boundary.py 本地验证。

共享配置的归属

配置解析模块(deerflow.config)属于 Harness 层,因为 App 和嵌入式客户端都需要读取配置。


设计取舍

Harness/App 拆分 vs 单体

方案优势代价
拆分Harness 可独立发布和嵌入增加一层抽象,需要维护导入防火墙
单体简单、无额外抽象无法嵌入使用,测试时需要完整 Web 栈

Deer-Flow 选择拆分,因为嵌入式客户端是其核心能力之一。


参考来源

  • Deer-Flow CLAUDE.md — Harness / App Split 章节
  • tests/test_harness_boundary.py — 导入防火墙测试