03 / Write Pipeline Audit

资料如何
可靠地变成知识

摄入不只是 Prompt,也不只是“写入成功”。可靠链路必须同时回答缓存为何有效、重试是否幂等、失败如何回滚、结论如何追溯、质量如何验收。

案例入口autoIngest()
模型阶段分析 → 生成 → 可选审核
现有边界Per-project Mutex
关键缺口跨文件事务 + 完整指纹

完整流水线

00 / prepare解析与缓存

复制来源、格式解析、MinerU、图片抽取、视觉描述。

01 / analyze结构化分析

识别实体、概念、主张、矛盾和现有 Wiki 关系。

02 / generate生成 FILE 块

输出来源页与领域页,附 frontmatter、sources 与 wikilink。

03 / commit校验并提交

解析、清洗、合并、修复、索引、日志、审核、缓存和向量。

入口 autoIngest(projectPath, sourcePath, llmConfig, ...) 先以“项目 + 来源”加锁, 允许不同来源的准备和模型生成并行,但把会改变 Wiki 的部分放进项目级提交边界。这样既争取吞吐,也避免多个来源同时覆盖聚合页。

来源进入系统

复制、路径与身份

显式导入会把文件复制到 raw/sources/;文件夹导入保留相对目录结构,并把诸如“papers > energy”这样的文件夹上下文交给模型辅助分类。 同名文件通过唯一目标路径处理,来源身份优先使用项目相对路径,避免不同子目录中同名文件互相污染。

格式解析

输入实现策略输出
PDF可选 MinerU;失败回退内置 PDFium。文本与图片均可缓存。Markdown + wiki/media 图片
DOC/DOCX/PPT/PPTXAnyDoc、docx-rs 或 ZIP/XML 结构提取,保留标题、列表、表格语义。结构化 Markdown
XLS/XLSX/ODScalamine / AnyDoc,按工作表转成 Markdown 表格。表格文本
EPUB/MOBI/Org专用电子书解析与 Org 文本提取。章节化文本
网页Chrome Clipper 用 Readability 清洗,再由 Turndown 转 Markdown。带 URL 的来源文件

解析结果保存在来源旁的 .cache/<filename>.txt;缓存只有在不早于原文件时才有效,结构化文档还带解析器格式标记以拒绝旧缓存。

多模态不是装饰

PDF、PPTX 和 DOCX 的内嵌图片先被提取到 wiki/media/<source-slug>/。只有图片路径没有语义时,文本模型常会在摘要中丢掉它; 因此流水线调用视觉模型生成事实性 alt 文本,再让后续知识页保留图文关系。

  1. Rust 从文档中抽取图片并统一保存。
  2. TypeScript 只对当前来源所属媒体目录中的图片生成描述。
  3. 图片内容以 SHA-256 缓存,相同 Logo 或图表模板不会重复付费。
  4. 即使模型漏写图片,程序也会向来源摘要页注入“Embedded Images”安全网。
  5. 注入新描述后重新向量化来源摘要,使图像语义可搜索。
主开关语义

关闭多模态时,代码不仅停止视觉调用,还会从发给生成模型的源文本中移除 Wiki 媒体引用,并跳过安全网注入,保证“关闭”不会通过另一条路径泄漏图片知识。

增量与长文策略

内容哈希缓存

checkIngestCache() 以来源内容和身份判断是否变化。命中时跳过昂贵的两次 LLM 调用,但仍允许图片管线补齐旧版本缺失的媒体或描述。 只有完整写入成功后才保存缓存;部分失败不会被当成已摄入。

缓存审计

当前摄入缓存核心是来源内容 SHA-256 和写入结果,并未形成包含解析器版本、Schema、Purpose、Prompt、模型、参数和代码版本的完整派生指纹。因此源文件不变时,规则或模型升级可能仍被判定为无需重建。

derivation_key = hash(source + parser + schema + purpose + prompt + model + parameters + pipeline_version)

长文档检查点

当来源超过稳定上下文预算,系统按语义边界切成约 12K–60K 字符的块,逐块分析,并维护全局 digest 和检查点。 最终把分块分析汇总成一个“Consolidated Long-Document Analysis”,再进入统一生成阶段。中断后可以从检查点恢复,避免从头消耗模型。

稳定上下文 = Schema + Purpose + Index + Overview + 来源预算
生成 Token 上限随 128K / 256K / 512K 上下文逐级扩大

两阶段 LLM:先理解,再写文件

Stage 1 · Analysis

温度设为 0.1、关闭额外 reasoning,以稳定格式提取:关键实体、概念、论点、与现有 Wiki 的连接、矛盾和建议页面结构。它不直接写磁盘。

Stage 2 · Generation

把第一阶段分析标为“只作上下文,不得复述”,要求响应第一字符就是 ---FILE:,以协议块输出文件:

---FILE: wiki/concepts/knowledge-compilation.md---
---
type: concept
title: Knowledge Compilation
sources:
  - raw/sources/example.pdf
---

# Knowledge Compilation
...
---END FILE---

生成 Prompt 同时传入 Schema、Purpose、当前索引、Overview、来源身份和来源全文。它明确禁止输出应用管理的 wiki/index.mdwiki/overview.md,并要求来源页链接回原始证据。

可选 Stage 3 · Review Suggestions

当资料规模或生成信号足够时,单独调用模型产生高价值 REVIEW 块。审核与文件生成分开,减少主输出被建议性文字污染。

把概率输出变成可靠文件

writeFileBlocks() 是模型世界与文件系统之间的重要校验层,但“有校验”不等于“有事务”。

协议解析

容忍围栏与少量格式偏差,但拒绝未闭合块、空内容和不安全路径。

内容清洗

规范 frontmatter、来源数组和日期,阻止模型写入应用管理路径。

创建或合并

新页面直接写入;已有页面通过专门合并 Prompt 保留旧信息、来源与人工编辑。

截断修复

若流在 FILE 中途结束,只请求模型重新生成缺失的完整文件块,并过滤越界输出。

写入后,程序确定性更新 Index;模型未生成 Log 时,程序追加标准格式日志;来源摘要缺失时,用 Stage 1 分析生成兜底页。 如果存在硬写入失败或未修复截断,任务抛错并保留已写文件,让重试可以在此基础上合并,而不是把半成品标成成功。 这是诚实的失败语义,却仍会把部分状态暴露给读者、索引器和后续重试;LLM 合并又具有非确定性,因此不能称为真正事务。

从单文件原子写到知识库提交

  1. 先生成不可变写入计划:目标路径、旧哈希、新哈希、来源与派生指纹。
  2. 全部内容写入 staging 目录,并完成 frontmatter、引用、链接和安全规则校验。
  3. 在提交日志中记录 intent,再以 manifest 指针或可恢复的重命名序列一次发布。
  4. 索引、向量和图谱只消费已提交版本;失败时忽略 staging,启动时扫描未完成 intent。
  5. 重试使用 operation_id 与预期旧版本做幂等和乐观并发检查,而不是盲目再次让模型合并。

队列与并发控制

  • 队列状态持久化到磁盘,应用重启后恢复待处理任务。
  • 解析并发可配置为 1–8;模型 worker 数量有独立上限。
  • 同一来源用源级互斥避免重复摄入,同一项目提交用项目锁序列化。
  • 失败最多自动重试 3 次;使用额度错误可等待约 15 分钟后自动恢复。
  • 用户可以暂停、恢复、移动、取消、批量重试或清除已完成任务。
  • 取消通过 AbortSignal 贯穿模型流、图片描述、写入前检查和活动状态。
并发模型

“准备与推理可并行,最终提交按项目串行”是合理起点,但进程内 Mutex 只约束单实例。CLI、编辑器、同步进程或第二个应用实例仍需要跨进程锁与乐观版本检查。

提交之后

  1. 解析 FILE/REVIEW 块,把待人工判断项写入 Review Store。
  2. 保存来源内容哈希、此次写入路径和长文检查点状态。
  3. 如果 Embedding 开启,跳过 index/log/overview,为新领域页建立分块向量。
  4. 刷新项目文件树并递增 dataVersion,使图谱与检索缓存失效。
  5. 活动面板记录成功、跳过、警告或失败;完整警告进入 .llm-wiki/ingest-warnings.log
案例已经做到

模型输出不直接等于成功;协议、路径、文件完整性、索引与缓存都有程序校验。这个方向正确,但目前的成功边界仍主要是“工程写入完成”,还没有覆盖跨文件原子性和知识语义正确性。

生产级写入的五个验收门槛

门槛必须回答建议指标
幂等同一操作重放会不会重复、漂移或覆盖人工修改?重复执行零非预期 diff
事务任一步崩溃后,读者会看见什么版本?故障注入后仅旧版或新版可见
血缘每个主张能否回到具体来源版本和文本跨度?引用可定位率、失效传播完整率
质量摘要是否忠实、合并是否丢信息、矛盾是否保留?支持率、遗漏率、冲突保留率
运行成本失败、重试、长文和多模态的预算是否可控?每文档成本、P95 延迟、重试率
通用原则

Prompt 只负责提出候选内容;Schema 校验、证据绑定、事务发布、质量评测和成本预算共同决定它是否能进入长期知识库。

Next Chapter04 · 检索提升如何被真正证明
案例证据:src/lib/ingest.tsingest-cache.tsingest-queue.tssource-preprocess.tsimage-caption-pipeline.tssrc-tauri/src/commands/fs.rs。派生指纹、staging/manifest 提交和五项验收门槛是本次审计提出的改进方案。