Skip to content

a-cdm 相对上游 deer-flow 的差异研究报告

生成于 2026-05-18 · 分析师:资深源码架构分析师(脚本式交叉分析)

输入基线

  • a-cdm 快照 commit 07b3469(本地);其内嵌的 vendored deer-flow 引擎
  • 上游 deer-flow main @ 39f901d3(2026-05-17,最新)
  • 两份 code-wiki:a-cdm 2026-05-18-034235(35 章)、deer-flow 2026-05-18-025019(36 章)

方法与可信度声明:本报告区分三类结论 ——

  1. 【确证 a-cdm 定制】 = 上游该目录/文件完全不存在(已用 ls 对两个工作区取 ground truth),或带显式 acdm/owner_sub 标记;
  2. 【确证版本漂移】 = 文件在上下游都存在且无 a-cdm 标记,差异来自上游 fork 后演进(a-cdm 落后),已用样本核验;
  3. 【疑似漂移,未确证】 = 纯上游目录内疑似改动但无法干净归因 —— 明确不计入 a-cdm 功劳/锅。

0. 一句话先行

a-cdm 不是「用 deer-flow 做个 ChatBot」,而是把 deer-flow 在 898f4e8(2026-04-17)整体冻结成 monorepo 内核,在其上(a)新增一个鉴权/授权/业务编排控制面 acdm-backend、(b)在引擎内外挂(而非改写)owner_sub 隔离 + 确定性 Pipeline + Agent-Tools BFF 三套定制扩展、(c)用 Aegra 替换 LangGraph Server 作 Agent Runtime,并独立挂一个与引擎正交的 ERP 录屏分析服务 demoo_service。引擎内核本体几乎原样保留,定制全部收敛在「上游不存在的新目录」与「两条 HTTP 契约」上。


1. 版本漂移 caveat(读全文前必须先接受的前提)

这是本报告最重要的一个事实,它决定了后面每一条结论怎么解读:

事实证据
a-cdm fork 起点上游 commit 898f4e8a —「fix: Memory update system…(#2251)」git show -s 898f4e82026-04-17 12:00
上游 wiki 基线39f901d3 —「fix(runs): restore historical runs…(#2989)」git show -s HEAD2026-05-17 20:03
中间演进量199 个提交,跨 ~1 个月git rev-list --count 898f4e8..HEAD = 199

推论(贯穿全报告):a-cdm/deer-flow~/repos/deer-flow 的任何 diff,只要落在纯上游文件里,默认方向是「a-cdm 落后于上游」,而不是「a-cdm 改动了它」。两个已核验的铁证:

  • 上游 packages/harness/deerflow/tools/sync.pytypes.py,a-cdm vendored 副本这两个文件 —— 是上游 fork 后新增,不是 a-cdm 删除。
  • 上游 models/mindie_provider.py 存在,a-cdm 副本 —— 同理,上游新增。

因此本报告不设「功能删」分类:在纯上游文件上看到的「少了东西」,绝大多数是 a-cdm 尚未 cherry-pick 上游新增,而非 a-cdm 主动删除。真正的 a-cdm 删除若存在,需在带 acdm 标记的文件里找,本次未发现。

同样地,上游 wiki 36 章描述的是 39f901d3 的代码,其中相当一部分机制(尤其 Runtime/persistence/中间件链的细节)比 a-cdm 内嵌副本新。引用上游 wiki 时本报告只用其作「上游基座本来长什么样」的参照,不假设 a-cdm 副本与之逐行一致。


2. 架构关系总览

2.1 a-cdm 三层 vs deer-flow 基座的关系

上游 deer-flow 自我定位是「super agent harness」,后端严格切成可发布的 deerflow.* harness 层不发布的 app.* 应用层,靠 tests/test_harness_boundary.py 的 AST 防火墙强制 deerflow → app 单向禁止(上游 wiki 09 章)。a-cdm 完整继承了这条边界,并在它外侧叠了自己的三层:

关键定性:橙色 EXT 是 a-cdm 定制的全部重心,它们都是上游目录级不存在的新增 —— a-cdm 的策略是「新增目录外挂,而非侵入上游文件改写」,这与红线「upstream 原生目录只读、改动限扩展点」(CLAUDE.md:26)完全吻合。这也是为什么 199 个上游提交带来的冲突面被刻意压低:定制几乎不踩上游会动的文件。

2.2 控制面 → 引擎 端到端数据流

证据链:acdm-backend/app/services/langgraph_client.py:43-44(引擎地址)、:100-115(4 头)、:155-156(owner_sub 注入);deer-flow/backend/packages/harness/deerflow/auth/acdm_auth.py:1-30(owner_sub 强制覆盖,文件头 docstring 明写「覆盖客户端任何传入值,防伪造」);deer-flow/backend/packages/harness/deerflow/tools/business_objects/client.py(反向 4 头);acdm-backend/app/main.py:255-268(mcp_service_auth 关口)。


3. 对 deer-flow 基座的改动(分类清单)

3.1 配置耦合【确证 a-cdm 定制】

改动内容证据归因
langgraph.json 改写graphs 从上游单一 lead_agent → 增加 weekly_report/meeting_aggregator/meeting_aggregator_realtime/ba_report 四个 pipeline;auth.path 从上游 ./app/gateway/langgraph_auth.py:auth 改指 ./packages/harness/deerflow/auth/acdm_auth.py:auth;checkpointer.path 也改指 harness 内路径上游 langgraph.json:11-12 auth 仍指 app/gateway/langgraph_auth.py;a-cdm deer-flow/backend/langgraph.json graphs 5 项确证定制
aegra.json 新增上游无此文件;a-cdm 新增,5 图均指向 ./aegra_graphs/*.py:graph,auth 同指 acdm_auth.pya-cdm deer-flow/backend/aegra.json;上游 ls 无确证定制
config.yaml 落地 + 火山方舟矩阵上游仓库只有 config.example.yaml(运行配置不入库);a-cdm 把 config.yaml 实体化并写入火山方舟 Coding Plan 9 模型矩阵(Doubao-Seed-2.0-pro/lite/code、GLM-4.7 等,api_base: …/api/coding/v3)a-cdm deer-flow/config.yaml:39-124;ls deer-flow/config.yaml → No such file确证定制(注:部分属「部署期运营配置」而非纯代码改动)

这三项是最危险的冲突面:langgraph.json 是上游会演进的文件,a-cdm 对它做了语义改写(改 auth 路径、加图),上游若同文件演进,cherry-pick 必冲突。

3.2 功能增:三大上游不存在的新目录【确证 a-cdm 定制】

均已用 ls 对两个工作区取 ground truth,上游对应目录完全不存在:

新增路径职责上游对照
owner_sub 鉴权层deer-flow/backend/packages/harness/deerflow/auth/(整包)LangGraph SDK Auth 扩展点,thread/run/store 按 owner_sub 隔离;ACDM_THREAD_AUTH_ENABLED=false 降级开关;admin 不走 bypass 改走独立 admin API上游 harness/deerflow/auth/ 目录不存在(上游 auth 在 app/gateway/langgraph_auth.py)
确定性 Pipelineharness/deerflow/pipelines/:weekly_report/meeting_aggregator/meeting_aggregator_realtime/ba_report非 Agent 的确定性 DAG 工作流,被 langgraph.json/aegra.json 注册为图上游 harness/deerflow/pipelines/ 目录不存在
Agent-Tools BFF clientharness/deerflow/tools/{business_objects,nc_primitives,project_primitives}/引擎侧 httpx helper,带 4 个 X-ACDM-* 头回调 acdm-backend /agent-tools/*上游 tools/ 仅有 builtins/skill_manage_tool.py/sync.py/tools.py/types.py,无此三子目录
Aegra 图工厂 wrapperdeer-flow/backend/aegra_graphs/(5 个 .py,各导出 graph)Aegra 0.9.4 只接受 ./path.py:var 不接受 module:var,故为每个图建 wrapper上游 backend/aegra_graphs/ 目录不存在(上游不用 Aegra)

补充证据:acdm_auth.py:1-30 docstring 自述「使用 LangGraph SDK 官方 Auth 扩展点……server-agnostic(LangGraph Server 0.7 + Aegra 0.9 同时兼容)」「降级开关 ACDM_THREAD_AUTH_ENABLED=false」—— 这是**典型的「用上游扩展点而非改上游代码」**的定制范式,值得肯定。

3.3 功能改:对上游文件的侵入式补丁【确证 a-cdm 定制,但面小】

a-cdm 对真正的上游文件改动极少,已知的边缘补丁(来自 a-cdm wiki 12/29 章 + 结构 diff):

  • deer-flow/backend/app/gateway/acdm_thread_auth.py(新文件,但被 routers/threads.py/uploads.py/artifacts.py 这些上游文件 import)—— 在上游 router 里插入 owner_sub 边缘校验。这是少数侵入上游文件的点,cherry-pick 风险点。
  • 前端 deer-flow/frontend/src/proxy.ts:Next.js 16 把 middleware.ts 重命名为 proxy.ts(上游演进)叠加 a-cdm 的 /workspace/* 守卫 + JWT 解码注入 —— 混合项:重命名是上游漂移,守卫逻辑是 a-cdm 定制,需分别看待。

3.4 功能删 —— 本报告不设此分类

见 §1:在纯上游文件上看到的「缺失」(如 tools/sync.pytools/types.pymodels/mindie_provider.py a-cdm 都缺)已核验为上游 fork 后新增、a-cdm 未跟进,属漂移,不是 a-cdm 删除。

3.5 前端定制【确证 a-cdm 定制】

模块a-cdm上游归因
frontend/src/core/acdm/27 个文件(owner-sub-store.ts/wiki-*/ba-report-*/knowledge-*/meeting-atoms.ts/calendar-*/screenshot-dedup/diff 等)1 项(基本为空)确证定制
frontend/tests/unit/core/acdm/13 个测试文件目录不存在确证定制
frontend/src/{app,components}/workspace/acdm/页面 + 组件(项目工作台/wiki 协编/会议日历)不存在确证定制(据 a-cdm wiki 28/30 章)

3.6 【疑似漂移,未确证为 a-cdm 改动】—— 显式排除项

以下不计入 a-cdm 定制,也不计入 a-cdm 的锅:

  • models/vllm_provider.pypatched_deepseek.py:上下游都存在(已核验上游 models/ 同样有这两文件)。结构 diff 阶段曾疑似为 a-cdm 定制,经 ground truth 核验为上游原生文件,予以更正 —— 非 a-cdm 新增。
  • models/mindie_provider.pytools/sync.pytools/types.py:上游有、a-cdm 缺 → 上游 fork 后新增、a-cdm 落后。
  • harness/deerflow/agents/sandbox/runtime/、中间件链、persistence 等纯上游目录内的任何逐行差异:在 199 提交的漂移下无法干净归因,默认视为「a-cdm 落后于上游」,不分析为 a-cdm 改动。上游 wiki(11/12/15/16 章)描述的这些机制是 39f901d3 版本,可能比 a-cdm 内嵌副本新。

4. a-cdm 净新增控制面与服务

4.1 acdm-backend(业务/鉴权/编排控制面)

完全自有、与 deer-flow 无代码共享(两进程、两套依赖)。规模(已核验):29 个 API router、36 个 service、40 个 alembic 迁移、3 ORM model 包。职责分层(a-cdm wiki 10/20-27 章 + acdm-backend/app/ ls):

  • 鉴权授权:auth/ —— Keycloak OAuth2 Code flow + HS256 cookie + Caddy forward_auth verify + 项目「成员/owner/admin」三级授权(require_project_access/require_project_owner)。
  • 业务域:项目/成员/SOW、会议域 + AI 原子抽取、会议洞察聚合、BA 专家报告(8 步 human-in-loop)、知识库/Wiki 协编(GitLab llm-wiki)、可逆 DB 操作(Actor 四模式 + saga rollback)。
  • 耦合层:services/langgraph_client.py(正向 SDK wrapper,封装 Aegra/LangGraph 差异、异常映射 50101/50102/50103)、mcp/(FastMCP 知识源 server,暴露 wiki/nextcloud 工具给引擎)、api/agent_tools_*(反向 BFF,3 个 X-ACDM 头解析身份 → via_agent actor)。
  • AI 治理(指挥室):app/util/ai_registry.py + app/ai_roles.yaml —— 集中声明所有 AI 功能的 provider/role/model ownership;managed_by: deer-flow 的 role 由 acdm-backend 拒绝直管(抛 BusinessException 50403,引导去 config.yaml);2026-05-08 prod 事故后改为 graceful degradation(provider 凭据缺失不 fail-fast,登记 unavailable,请求期返 503),结构错仍 fail-fast。
  • 启动序列(main.py:_lifespan):init_registry(fail-fast)→ install_db_event_recorder → install_ai_extract_listener + recover_pending_on_startup → probe_streaming_roles(graceful)→ MCP server → background_executor → ba_report_sync_scheduler。
  • 项目 Agent provision:项目创建钩子 HTTP POST deer-flow-gateway:8001/api/agents 创建 project-{slug} agent(失败 graceful,可手工 backfill)—— 控制面驱动引擎侧 Agent 拓扑的体现。

价值:它是「Agent 引擎不懂业务、不该管鉴权」与「企业业务/安全治理」之间的适配层与安全边界。引擎保持通用,所有 a-cdm 专属业务语义、可逆性、租户隔离都在这一层,引擎零业务污染 —— 这正是 §2.1「外挂不侵入」策略在控制面侧的落地。

4.2 demoo_service(ERP 录屏分析与 PRD 流水线)

Flask + Flask-CORS,入口 demoo_service/server.py(app.run(host='0.0.0.0', port=8088)),60+ API 端点。核心:

  • erp_flow 四阶段流水线(代码佐证):提取 erp_flow/stages/extractor.py:CompactExtractor → 合并 merger.py:ContextMerger(Jaccard 聚类)→ 纪要 transcript.py:TranscriptLoader → 生成 generator.py:PRDGenerator
  • 页面类型识别:erp_flow/stages/page_type_detector.py:detect_page_type 识别 login/query_list/form_detail/dashboard_home 四类(金蝶云星瀚 selector 语义)。
  • 零插件直采录制:proxy_recorder.py:proxy_bp,反向代理转发目标 ERP 并注入 recorder_inject.js 客户端捕获。
  • 集成关系:与 acdm-backend 共享 platform-db(config.py:145「与 acdm-backend 共用 platform-db」,写 {schema}.recording_result)、归档录屏到 Nextcloud(nextcloud_uploader.py);对 acdm-backend 仅条件软导入(server.py:2894 按需 from backend import ERPAnalyzer),非硬依赖。
  • 与 deer-flow 引擎关系:无直接依赖(grep 未发现 deerflow/langgraph import);AI 能力走自己的 LLM 链路(腾讯云 aicc Kimi-K2.5 + doubao-seed Anthropic 兼容端点),不经引擎、不经 acdm-backend 中转

定位一句话:demoo_service 是与 Agent 引擎正交的领域专门化子系统,负责「ERP 现状录屏 → 结构化 → PRD」,通过共享数据库/文件而非代码或 HTTP 契约与主系统松耦合 —— 它是 a-cdm「三大组成」里耦合度最低的一块,可独立演进甚至独立部署。


5. 集成与数据流(端到端)

阶段通道身份/凭据关键文件
用户 → 控制面Caddy forward_auth → acdm-backendKeycloak cookie → X-Auth-User-* 4 头deploy/prod/Caddyfile.keycloak-v1acdm-backend/app/auth/
用户 → 引擎(SSE)前端 /api/langgraph/* 直连 Aegra同 4 头(proxy.ts 注入)deer-flow/frontend/src/proxy.ts
控制面 → 引擎(正向)LangGraph SDK(httpx 单例,read_timeout 900s)_auth_headers() 同名 4 头 + metadata.owner_sublanggraph_client.py:43-197
引擎 owner_sub 闭环Aegra Auth 扩展点acdm_auth.on_thread_create 强制覆盖 owner_subacdm_auth.py:1-30
引擎 → 控制面(反向)Agent-Tools BFF httpxX-ACDM-Service-Auth(service token)+ X-ACDM-User/Agent/Threadtools/business_objects/client.pymain.py:255-268
反向 → 可逆操作reversible_actor_context 中间件X-ACDM-User-Idvia_agent actoracdm-backend storage 层
demoo 旁路不经引擎,共享 DB/NC自有 LLM 凭据demoo_service/db.pynextcloud_uploader.py

两条 HTTP 契约是整个耦合的全部接触面:正向(去引擎)回答「这个 run 属于哪个用户」(owner_sub 隔离),反向(回控制面)回答「哪个 Agent 代表哪个用户在哪个 thread 调我」(可逆 actor)。两套头方向严格不混(X-Auth-User-* vs X-ACDM-*)。没有共享 Python 代码、没有共享进程 —— 这是 a-cdm「深度二开但进程仍解耦」的精髓,也是它能扛住 199 提交漂移的结构原因。


6. 升级风险与建议

6.1 风险盘点

风险等级说明
fork 已落后 199 提交 / 1 个月a-cdm 内嵌副本停在 898f4e8(2026-04-17),上游已到 39f901d3。安全/稳定性修复(如上游 #2989 runs 持久化恢复、#2973 PVC 按用户隔离、#2987 skills 安全扫描健壮性)未进入 a-cdm,需手工 cherry-pick 评估。
langgraph.json 语义改写冲突面a-cdm 改了 auth.path/checkpointer.path 并加了 4 图。上游同文件持续演进,这是最可能 cherry-pick 冲突的单点
acdm_thread_auth.py 侵入上游 router被上游 routers/{threads,uploads,artifacts}.py import;上游若重构这些 router,补丁失效或冲突。
Aegra 替换 LangGraph Servera-cdm 用 Aegra 0.9.4 替换上游 Runtime,上游 Runtime/persistence(wiki 15/16 章)持续演进,两套 checkpointer/runs 语义会渐行渐远;RUNTIME_BACKEND=langgraph 回滚路径依赖上游兼容性,长期不可靠。
config.yaml 入库低-中上游 config.yaml 不入库(只有 example),a-cdm 入库了带模型矩阵的实体文件;cherry-pick config.example.yaml 的 schema 演进时需手工对齐。
定制点维护成本5 个外挂目录 + acdm-backend 36 service 长期需自维护,但因「不侵入上游文件」,成本主要在「跟随上游扩展点 API 变更」,而非合并冲突。

6.2 建议(给维护者)

  1. 建立 cherry-pick 节流闸:898f4e8..upstream/main 已 199 提交,不可能全量跟。建议每月跑一次 git log --oneline 898f4e8..upstream/main -- backend/packages/harness/deerflow/{auth,runtime,agents},只筛安全/数据正确性 fix(如 #2251 内存损坏类、#2989 runs 恢复类)定向 cherry-pick,常规 feature 不跟。把已 cherry-pick 的 commit 列表记入 docs/runbooks/vendored-sync.md,避免重复评估。
  2. 冻结并文档化 langgraph.json/aegra.json 的定制语义:这是冲突最高发点。建议在两文件旁加 README 注明「auth/checkpointer 路径为 a-cdm 定制、cherry-pick 上游此文件时务必保留」,并写一个 CI 断言校验 auth.path == acdm_auth.py,防止 cherry-pick 静默回退鉴权到上游 langgraph_auth.py(将造成 owner_sub 隔离失效的安全事故)。
  3. acdm_thread_auth.py 对上游 router 的侵入降到 0:目前它被上游 router import,是唯一侵入点。评估能否改为上游 Auth 扩展点统一拦截(acdm_auth.py 已是此范式),让 routers/{threads,uploads,artifacts}.py 回到上游原样,彻底消除该冲突面。
  4. 给 Aegra 替换写一份「上游 Runtime 演进影响评估」runbook:明确哪些上游 Runtime/persistence 变更与 Aegra 无关(可忽略)、哪些影响 checkpointer schema(需同步)。RUNTIME_BACKEND=langgraph 回滚路径应定期实测,否则它只是名义上的应急开关。
  5. demoo_service 可考虑独立仓:它与引擎正交、与 acdm-backend 仅共享 DB/NC、AI 链路独立,留在 monorepo 只增加 monorepo 体积与 CI 时间而无集成收益。若团队带宽允许,拆出可降低主仓认知负载(此为优化项,非紧急)。

7. 结论

本质定位一句话:a-cdm = 「在 2026-04-17 冻结的 deer-flow 引擎之上,用『新增外挂目录 + 两条 HTTP 契约 + 一个净新增控制面』构建的、面向交付项目的『数字同事』系统」—— 引擎是借来的发动机且刻意不改它的内脏,a-cdm 的全部价值与全部维护负担都在引擎之外的外挂层和控制面。

给维护者的 5 条建议(优先级序):

  1. 【紧急】langgraph.json/aegra.json 加 CI 断言锁住 auth.path = acdm_auth.py —— 防 cherry-pick 静默回退鉴权造成 owner_sub 隔离失效(数据越权风险)。
  2. 【高】 建立每月「安全/数据正确性 fix 定向 cherry-pick」机制,记账于 vendored-sync.md;199 提交里至少 #2251 类内存损坏、#2989 类 runs 恢复值得评估。
  3. 【高】 消除 acdm_thread_auth.py 对上游 router 的侵入,统一收敛到 acdm_auth.py 的 Auth 扩展点范式,把上游文件冲突面降到 0。
  4. 【中】 为 Aegra 替换写「上游 Runtime 演进影响评估」runbook,并定期实测 RUNTIME_BACKEND=langgraph 回滚路径的真实可用性。
  5. 【中/优化】 评估把 demoo_service 拆出 monorepo(正交、低耦合、独立 AI 链路,留在主仓无集成收益)。

方法论备注:本报告所有「a-cdm 定制」结论均以「上游目录/文件 ground truth 不存在」或显式 acdm 标记为依据;所有纯上游文件差异默认归为「a-cdm 落后于 199 提交的漂移」,不计入 a-cdm 功劳或锅。vllm_provider.py/patched_deepseek.py 经核验更正为上游原生(非 a-cdm 新增)。无法干净归因的项已在 §3.6 显式列出并排除。

公司内部参考 · 由 claude-wiki-gen 基于源码自动生成的二次分析