Skip to content

编译流水线

编译流水线通过四个顺序执行的 LLM 阶段将原始内容转化为结构化 wiki 文章。Go 后端负责编排并发执行;Python AI 引擎(kb-ai)执行实际的 LLM 调用。

流水线概览

┌─────────┐    ┌──────────┐    ┌───────┐    ┌───────┐
│ Extract │───▶│ Classify │───▶│ Write │───▶│ Index │
└─────────┘    └──────────┘    └───────┘    └───────┘
   并行执行       顺序执行        顺序执行      顺序执行

Extract 阶段在 worker 池中并行运行。一批任务提取完成后,剩余阶段在 Pipeline Worker 中按用户顺序执行。

阶段 1:Extract(提取)

目标:从原始文本中提取结构化信息。

Extract 阶段读取提交的内容,产出结构化提取结果,包含:

  • 概念和实体
  • 决策及其依据
  • 行动项和责任人
  • 关键事实和关联关系

提取策略

策略适用场景工作方式
chunked短到中等长度文档分块后独立提取每个块
summarize长文档、会议转写先用便宜模型分块摘要,再从摘要中提取
auto默认策略根据 chunk 数量自动选择 chunkedsummarize

summarize 策略对长内容(会议记录、大型文档)显著更省成本,因为摘要阶段使用更小的模型,将压缩后的文本再交给提取模型处理。

并行执行

Go Dispatcher 将 Extract 任务分配给 worker 池(默认 4 个)。每个 worker 独立调用 Python AI 引擎的 /extract 端点。多个文档同时提取,受 Dispatcher 信号量约束。

阶段 2:Classify(分类)

目标:决定每个提取项在 wiki 中的归属。

Classify 阶段检查提取结果和当前 wiki 结构,然后:

  1. 将提取项映射到现有 wiki 文章(用于合并)
  2. 识别需要新建文章的项
  3. 对相关项进行分组,避免碎片化

该阶段读取当前 master-index.md 以了解现有 wiki 拓扑结构。

阶段 3:Write(写入)

目标:生成或更新 Markdown 文章。

根据分类结果,Write 阶段执行:

  • 创建——从提取项生成新的 Markdown 文章
  • 合并——将新信息融入现有文章,去重并重新组织结构

输出为规范的 Markdown,含标题、列表和互链——设计上兼顾人类阅读和 LLM 消费。

阶段 4:Index(索引)

目标:保持导航索引最新。

文章写入后,Index 阶段更新:

  • master-index.md——顶层目录,供 LLM 检索时导航
  • Topic indexes——按主题分组的相关文章索引
  • People stubs——提到的人物的简要参考页

master-index 是关键产物:它是所有 LLM 迭代检索查询的入口。

增量编译

KaaS 只重新编译新增或变更的内容。当提交与现有 wiki 内容重叠的材料时:

  1. Extract 仅处理新提交的内容
  2. Classify 识别与现有文章的重叠
  3. Write 执行合并(非替换)——保留现有内容的同时整合新信息
  4. Index 仅刷新受影响的条目

这意味着提交 10 个文档不会重新处理之前的 100 个。

并发与加速

Worker Pool 架构图

Dispatcher(调度器)

Dispatcher 是中央协调器:

  • 按可配置间隔轮询任务队列(poll_interval_ms
  • 以租约方式认领任务(防止重复处理)
  • 通过 Go channel 信号量强制并发上限
  • 断路器打开时暂停认领

Extract Worker Pool(提取工作池)

多个 goroutine 并行处理 Extract 任务:

  • 默认并发度:4 个 worker(配置项 extract_workers
  • 每个 worker 通过 HTTP 调用 Python 的 /extract 端点
  • 进度通过 SSE 流式推送到前端

Pipeline Worker(流水线工作器)

提取完成后,单个 Pipeline Worker 按用户批次执行剩余阶段:

  • Classify → Write → Index 顺序执行
  • 将同一用户所有待处理的提取结果批量处理
  • 调用 Python 的 /pipeline-stream 端点(SSE 进度)

Circuit Breaker(断路器)

防御 LLM 供应商故障:

参数默认值说明
cb_failure_threshold5连续失败次数阈值,触发打开状态
cb_cooldown_sec30打开后进入半开探针的冷却秒数

状态机:

  1. Closed(关闭)——正常运行;失败递增计数器
  2. Open(打开)——所有调用立即拒绝;Dispatcher 停止认领任务
  3. Half-Open(半开)——冷却期后允许一个探针请求;成功则关闭断路器,失败则重新打开

Lease & Heartbeat(租约与心跳)

每个认领的任务携带一个带超时的租约(lease_timeout_sec,默认 300 秒)。Worker 通过心跳定期续约。如果 worker 崩溃:

  • 租约到期
  • Dispatcher 的 RecoverExpired 扫描将任务重新入队
  • 另一个 worker 接手处理

这保证了至少一次(at-least-once)处理,无需人工干预。

配置参考

所有编译流水线设置位于 etc/kaas.toml[worker] 节:

toml
[worker]
extract_workers = 4          # Extract 并行 worker 数
pipeline_concurrency = 2     # Pipeline worker 并发度
poll_interval_ms = 1000      # 队列轮询间隔(ms)
lease_timeout_sec = 300      # 租约超时后恢复(s)
cb_failure_threshold = 5     # 连续失败多少次打开断路器
cb_cooldown_sec = 30         # 断路器冷却期(s)