主题
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-flow2026-05-18-025019(36 章)方法与可信度声明:本报告区分三类结论 ——
- 【确证 a-cdm 定制】 = 上游该目录/文件完全不存在(已用
ls对两个工作区取 ground truth),或带显式acdm/owner_sub标记;- 【确证版本漂移】 = 文件在上下游都存在且无 a-cdm 标记,差异来自上游 fork 后演进(a-cdm 落后),已用样本核验;
- 【疑似漂移,未确证】 = 纯上游目录内疑似改动但无法干净归因 —— 明确不计入 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 898f4e8 → 2026-04-17 12:00 |
| 上游 wiki 基线 | 39f901d3 —「fix(runs): restore historical runs…(#2989)」 | git show -s HEAD → 2026-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.py、types.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.py | a-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) |
| 确定性 Pipeline | harness/deerflow/pipelines/:weekly_report/meeting_aggregator/meeting_aggregator_realtime/ba_report | 非 Agent 的确定性 DAG 工作流,被 langgraph.json/aegra.json 注册为图 | 上游 harness/deerflow/pipelines/ 目录不存在 |
| Agent-Tools BFF client | harness/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 图工厂 wrapper | deer-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.py、tools/types.py、models/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.py、patched_deepseek.py:上下游都存在(已核验上游models/同样有这两文件)。结构 diff 阶段曾疑似为 a-cdm 定制,经 ground truth 核验为上游原生文件,予以更正 —— 非 a-cdm 新增。models/mindie_provider.py、tools/sync.py、tools/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-seedAnthropic 兼容端点),不经引擎、不经 acdm-backend 中转。
定位一句话:demoo_service 是与 Agent 引擎正交的领域专门化子系统,负责「ERP 现状录屏 → 结构化 → PRD」,通过共享数据库/文件而非代码或 HTTP 契约与主系统松耦合 —— 它是 a-cdm「三大组成」里耦合度最低的一块,可独立演进甚至独立部署。
5. 集成与数据流(端到端)
| 阶段 | 通道 | 身份/凭据 | 关键文件 |
|---|---|---|---|
| 用户 → 控制面 | Caddy forward_auth → acdm-backend | Keycloak cookie → X-Auth-User-* 4 头 | deploy/prod/Caddyfile.keycloak-v1、acdm-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_sub | langgraph_client.py:43-197 |
| 引擎 owner_sub 闭环 | Aegra Auth 扩展点 | acdm_auth.on_thread_create 强制覆盖 owner_sub | acdm_auth.py:1-30 |
| 引擎 → 控制面(反向) | Agent-Tools BFF httpx | X-ACDM-Service-Auth(service token)+ X-ACDM-User/Agent/Thread | tools/business_objects/client.py、main.py:255-268 |
| 反向 → 可逆操作 | reversible_actor_context 中间件 | X-ACDM-User-Id → via_agent actor | acdm-backend storage 层 |
| demoo 旁路 | 不经引擎,共享 DB/NC | 自有 LLM 凭据 | demoo_service/db.py、nextcloud_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 Server | 中 | a-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 建议(给维护者)
- 建立 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,避免重复评估。 - 冻结并文档化
langgraph.json/aegra.json的定制语义:这是冲突最高发点。建议在两文件旁加README注明「auth/checkpointer 路径为 a-cdm 定制、cherry-pick 上游此文件时务必保留」,并写一个 CI 断言校验auth.path == acdm_auth.py,防止 cherry-pick 静默回退鉴权到上游langgraph_auth.py(将造成 owner_sub 隔离失效的安全事故)。 - 把
acdm_thread_auth.py对上游 router 的侵入降到 0:目前它被上游 router import,是唯一侵入点。评估能否改为上游 Auth 扩展点统一拦截(acdm_auth.py已是此范式),让routers/{threads,uploads,artifacts}.py回到上游原样,彻底消除该冲突面。 - 给 Aegra 替换写一份「上游 Runtime 演进影响评估」runbook:明确哪些上游 Runtime/persistence 变更与 Aegra 无关(可忽略)、哪些影响 checkpointer schema(需同步)。
RUNTIME_BACKEND=langgraph回滚路径应定期实测,否则它只是名义上的应急开关。 - demoo_service 可考虑独立仓:它与引擎正交、与 acdm-backend 仅共享 DB/NC、AI 链路独立,留在 monorepo 只增加 monorepo 体积与 CI 时间而无集成收益。若团队带宽允许,拆出可降低主仓认知负载(此为优化项,非紧急)。
7. 结论
本质定位一句话:a-cdm = 「在 2026-04-17 冻结的 deer-flow 引擎之上,用『新增外挂目录 + 两条 HTTP 契约 + 一个净新增控制面』构建的、面向交付项目的『数字同事』系统」—— 引擎是借来的发动机且刻意不改它的内脏,a-cdm 的全部价值与全部维护负担都在引擎之外的外挂层和控制面。
给维护者的 5 条建议(优先级序):
- 【紧急】 给
langgraph.json/aegra.json加 CI 断言锁住auth.path = acdm_auth.py—— 防 cherry-pick 静默回退鉴权造成 owner_sub 隔离失效(数据越权风险)。 - 【高】 建立每月「安全/数据正确性 fix 定向 cherry-pick」机制,记账于
vendored-sync.md;199 提交里至少 #2251 类内存损坏、#2989 类 runs 恢复值得评估。 - 【高】 消除
acdm_thread_auth.py对上游 router 的侵入,统一收敛到acdm_auth.py的 Auth 扩展点范式,把上游文件冲突面降到 0。 - 【中】 为 Aegra 替换写「上游 Runtime 演进影响评估」runbook,并定期实测
RUNTIME_BACKEND=langgraph回滚路径的真实可用性。 - 【中/优化】 评估把 demoo_service 拆出 monorepo(正交、低耦合、独立 AI 链路,留在主仓无集成收益)。
方法论备注:本报告所有「a-cdm 定制」结论均以「上游目录/文件 ground truth 不存在」或显式
acdm标记为依据;所有纯上游文件差异默认归为「a-cdm 落后于 199 提交的漂移」,不计入 a-cdm 功劳或锅。vllm_provider.py/patched_deepseek.py经核验更正为上游原生(非 a-cdm 新增)。无法干净归因的项已在 §3.6 显式列出并排除。