第 2 章 全景:四服务架构与数据流水线

本章目标:建立整个系统的空间感(谁在哪、谁跟谁说话)和时间感(数据怎么一步步流动)。
学完你能回答:四个服务各自管什么?六个数字目录是什么契约?一次完整生成要多久、卡在哪?
LLM 调用发生在哪些点?

2.1 四服务怎么分工

                   ┌────────────────────── 共享层 ──────────────────────┐
                   │  model_core(LLM 客户端/统一实体标准/提示词库)        │
                   │  modules/common(阶段映射/模板章节词表/日志)          │
                   └───────▲──────────────▲──────────────▲──────────────┘
                           │              │              │
docx ──> convert2md──┤   generator          ├── evaluator
       (文档转换服务)      │  (实体/要点/用例生成服务)  │   (质量评估服务)
                           │              │              │
                           └────── dashboard───────┘
                                (统一工作台:界面/编排/归档)

三个反直觉但重要的架构事实:

  1. 服务间零直接 RPC。generator 不调用 convert2md,evaluator 也不调用 generator。跨服务数据传递全部 通过文件系统契约(下一节的六阶段目录)完成;跨服务任务触发全部由 dashboard 前端(浏览器) 逐阶段 POST 驱动。这样任何一个服务重启/挂掉都不影响其他服务的存量任务。
  2. dashboard 是薄 BFF。它只代理数据面(文件列表、归档、日志),生成任务由浏览器持配置直连三个后端服务 (GET /config 把服务 URL 发给前端)——长任务不过 BFF 中转,避免代理超时把生成链拖死。
  3. 共享层"厚"。LLM 怎么调、实体长什么样、日志怎么打,这些四服务共用的规则全部收在 model_coremodules/common,业务服务里不许出现副本。

2.2 六阶段目录契约:文件名即协议

所有数据落在 data/ 下(运行时目录,gitignore),按阶段分目录、按时间戳命名:

data/workspace/(工作区——正在处理的数据)
  01_raw/          上传的原始 docx/xlsx
  02_markdown/     转换产物  *_SRC_20260911_095238.md
  03_entity/       实体产物  *_ENT_20260911_115846.json
  04_point/        要点产物  *_PNT_20260911_170512.json
  05_case/         用例产物  *_CAS_20260912_025833.json
  06_eval/         评估产物  *_EVAL_20260912_033812.json

data/projects/{项目名}/(归档区——按项目整理的历史版本)
  02_markdown/ ~ 06_eval/(与 workspace 同构)

2.3 一次端到端数据旅行(真实批次实录)

以 A3 批次(2026-09-11,挂机二期文档,人工验收时跑的完整链)为例,看真实的时间线:

时刻 站点 发生了什么 产物
09:52 上传转换 docx 上传,convert2md 异步转换(25 张图逐张 VLM 理解) SRC_20260911_095238.md(18953 字)
11:30 新建生成 用户在 dashboard 生成监控视图点"新建生成",前端 TaskHub 开始驱动四阶段链 会话 sess_1789097412
11:58 实体提取 generator 逐节 LLM 提取,28 分钟 ENT 647 实体
17:05 测试要点 逐实体四象限生成(约 5.2 小时,LLM 调用最密集段) PNT 642 要点
02:58 测试用例 逐要点展开用例(跨夜,约 8.5 小时) CAS 8863 用例(1.26GB)
03:38 评估 evaluator 对照原文评分 EVAL overall 72.49

全链约 18 小时(81 个实体节点规模的文档)。三个值得记住的量级感:

  1. 时间大头在 LLM 调用:要点 + 用例两段 13+ 小时,本质是"每个节点一趟 LLM 请求 × 网关延迟"。 本工程近期的提速改造(并发池 5→8、Self-RAG 触发式、紧凑序列化)都是对着这个瓶颈去的 (第 5.4 节详讲)。
  2. 产物可以很大:8863 条用例的 JSON 有 1.26GB——所以前端有"超 512MB 不预载"的护栏, 新人写消费 CAS 的代码时要有时时刻刻的量级警觉。
  3. 链是浏览器驱动的:中间用户关了浏览器,链就断了(服务端单任务照跑完,但后续阶段无人续接)。 这是刻意的架构取舍,第 8 章详讲边界与补救。

2.4 LLM 角色地图:哪里用 LLM、哪里不用

新人最容易建立的错误印象是"这是个 LLM 项目,所以到处在调 LLM"。实际地图(★=LLM 调用点):

环节 用 LLM 吗 说明
docx→md 格式映射 纯 python-docx 确定性代码
docx→md 层级修复(HYBRID 模式) ★(可选) 启发式检测到层级问题才请 LLM 修复,失败回退
图片理解 每张图一趟视觉模型(glm 视觉通道)
约定区切分 ✗(默认) 词表规则切;LLM 兜底路径存在但触发面≈0
约定区意图卡片蒸馏 ★(生产开) preamble 压缩省 tokens(glm-5.3-flash 轻模型)
实体提取 逐节一趟主生成模型
跨节依赖确认 ★(预筛后) 关键词预筛,命中才轻量确认,默认拒绝
要点生成 逐原子实体一趟
要点 Self-RAG 反思 ★(触发式) 仅完整性门/vague 触发时(生产 gated 模式)
用例生成 逐要点一趟
向量嵌入 ✗(本地模型) bge-m3 本地推理,不走 LLM 网关
检索重排 BgeReranker 本地 cross-encoder(LLM 重排另有 flag,生产开)
评估:覆盖率/结构/规范 全部确定性代码
评估:geval 评审 采样 20 条用例 × 3 维度

规律很清晰:LLM 只做"语义判断"(读图、读文、写要点、写用例、评质量),
一切有确定答案的事(格式、计数、覆盖率、层级合法性)都交给代码。
此外还有一条选型维度:模型分档——重活(生成)用 glm-5.3 主力模型,轻活(意图卡片蒸馏)用
glm-5.3-flash 省成本。这套"重轻分离"在第 9 章技术栈里展开。

2.5 小结



↙↙↙阅读原文可查看相关链接,并与作者交流