LLM Wiki应用之认知流水线篇——AI Agent读取89份PDF

75 分钟。89 份 PDF。164 个候选主题。11 个新建页面。20 个更新页面。

这是 2026 年 6 月 19 日,我的 AI Agent 完成的一次批量知识摄入。输入是海思 Hi3519DV500 原厂 SDK 的全部技术文档(89 份 PDF,涵盖芯片手册、编程指南、硬件设计参考、驱动开发文档),输出是一个结构化的嵌入式 Linux Wiki------从 14 页涨到 25 页。

这篇文章拆解 Agen 的完整认知流水线------它怎么"读"、怎么"理解"、怎么"决策"、怎么"写"。


老规矩先看效果

摄入前后对比:

指标 摄入前 摄入后 变化
实体页 3 6 +3(Hi3516DV500、ToolPlatform、SVP NPU 工具链)
概念页 11 18 +7(裸烧升级、U-Boot 移植、SDK 安装、外设驱动、安全启动...)
对比页 0 1 +1(Hi3519 vs Hi3516)
更新已有页 --- 4 AI ISP、MPP 流水线、NPU 推理、启动配置
总页面数 14 25 +11

决策分布:

决策 数量 占比
建页 11 12%
更新 20 17%
跳过 ~133 71%
候选总数 ~164 100%

71% 的跳过率不是"遗漏"------是精准过滤。


流水线全景:6 个阶段

Agent 的摄入流水线分为 6 个阶段,每个阶段有明确的输入、输出和决策逻辑:

复制代码
Phase 1: 文件采集   → Phase 2: 文本提取   → Phase 3: 内容理解
Phase 4: 决策分类   → Phase 5: 页面生成   → Phase 6: 交叉引用

Phase 1:文件采集------把 PDF 变成 Agent 能读的格式

输入: 89 份 PDF,散落在 SDK 的 ReleaseDoc/zh/ 目录下。

Agent 的动作:

第一步------结构化归档。Agent 扫描了所有 PDF 文件名和目录结构,按照内容主题分为 3 大类、10 个子目录:

复制代码
raw/docs/
├── 00.hardware/          # 硬件设计类
│   ├── 芯片数据手册/
│   ├── 硬件设计指南/
│   └── 引脚定义/
├── 01.software/          # 软件开发类
│   ├── SDK 开发指南/
│   ├── 驱动开发/
│   ├── AI ISP 开发/
│   └── 工具链使用/
└── 02.reference/         # 参考类
    ├── API 参考手册/
    ├── 寄存器手册/
    └── 版本说明/

这个分类不是让 Agent 看着玩的------它影响 Phase 4 的决策。hardware/ 下的 PDF 更可能产生 entity 页面(芯片、传感器),software/ 下的 PDF 更可能产生 concept 页面(驱动开发方法论、编译流程)。

第二步------文本提取。Agent 用 pymupdf 逐份读取 PDF,提取纯文本。每份 PDF 保存为 raw/docs/ 下的 .md 文件,并在 frontmatter 记录 source_url、ingested 时间、和 sha256 哈希(用于后续漂移检测)。

关键决策: 为什么不直接用 PDF 原文?因为 Agent 需要用 search_files 在 raw/ 中搜索关键词------PDF 二进制文件无法被 grep。转成 .md 后,全 Wiki 的内容搜索可以覆盖 raw/ 目录。


Phase 2:文本提取------PDF 的三大技术坑

PDF 看起来像文本,但内部结构是一堆"在坐标 (x, y) 处画字符 'A'"的指令。Agent 必须把这些指令还原为可读的段落。

坑一:表格提取。 PDF 的表格是用坐标位置对齐的,不是 HTML 的
标签。Agent 用 X 坐标聚类算法:把页面所有字符按 X 坐标分组------同一组 X 坐标的字符属于同一列。然后按 Y 坐标排序------同一行。最终重建出正确的表格结构。

效果:原厂芯片手册里的寄存器定义表(100+ 行 × 5 列,多页跨页)被正确提取为 Markdown 表格。

坑二:页眉页脚。 每页 PDF 的顶部和底部有重复的"Hi3519DV500 数据手册 V1.0"和页码。Agent 用编辑距离算法检测跨页重复文本行------连续 3 页以上出现在同一位置、相似度 > 90% 的文本块被识别为页眉/页脚,自动去除。

坑三:多栏布局。 部分参考手册使用了双栏排版。Agent 检测页面中间是否有持续的垂直空白区------如果有,先按栏拆分再提取,避免 A 栏第 1 行 + B 栏第 1 行混排。


Phase 3:内容理解------从文本到候选主题

提取完文本后,Agent 不是立刻开始建页------它先"读"。

阅读策略:先读索引文档,再读正文。

Agent 按照优先级读取文件:

  • 优先级 1: 目录文件、产品简介------了解整体结构
  • 优先级 2: 核心设计文档------芯片架构、BSP 开发指南
  • 优先级 3: 具体功能文档------传感器驱动、NPU 使用、电源设计

这样读的原因是:读了产品简介后,Agent 知道 Hi3519DV500 有双核 A55 + NPU + AI ISP + MIPI 接口 + DDR4。然后读各模块文档时,自动把信息归入已有的概念------不会为"MIPI 接口"新建一个和"外设接口总览"重复的页面。

关键词提取与聚类:

Agent 从全部文本中提取了约 500 个高频术语。然后用 TF-IDF 计算每个术语在文档中的重要性------不是出现次数多就重要,而是"在当前文档中出现频率高但在其他文档中出现频率低"的术语才重要。

结果:164 个候选主题。其中 37 个是芯片/传感器名称,127 个是技术概念。


Phase 4:决策分类------建页 vs 更新 vs 跳过

这是整个流水线的核心判断。Agent 对 164 个候选主题逐一分类:

决策规则(来自 SCHEMA.md):

判断一个候选主题是否需要建页:

  • ✅ 出现在 2+ 个不同来源中 → 建页
  • ✅ 是某个来源的核心主题 → 建页
  • ❌ 只是顺带提及 → 跳过
  • 📝 是对已有页面的补充 → 更新已有页

三个典型案例:

案例一:Hi3516DV500(建页)。 这个芯片在多份文档中被提及,每次都是和 Hi3519DV500 做对比------"相比 Hi3519,Hi3516 无 NPU 单元"。满足"2+ 来源"条件 → 建页。

案例二:SVB 动态调压(更新已有页)。 电源管理页面已经存在。PDF 中有 3 页专门讲 SVB 调压原理和寄存器配置。Agent 判断:核心主题但不是新概念,应补充到已有页面 → 更新电源管理。

案例三:DDR PHY Training(跳过)。 PDF 的 DDR 初始化章节提到 PHY Training 概念。但只有 2 段话,没有深入展开。Agent 判断:顺带提及 → 跳过。这个信息被嵌入 DDR4 接口设计页面的一小段里,不需要独立建页。

批量决策效率: 164 个候选主题,Agent 的决策过程约 8 分钟。不是每个主题独立分析------Agent 先对所有候选做关键词聚类(37 个同类芯片名合并为 3 个页面候选、127 个概念合并为约 40 个页面候选),再批量判断。


Phase 5:页面生成------从候选到结构化 Markdown

建页模板:

每个新建页面遵循统一结构:

  • YAML frontmatter(title / created / type / tags / sources / confidence)
  • 概述段落(一句话说清楚这是什么)
  • 主体内容(按逻辑分段,每段 ≤ 5 句话)
  • \[wikilinks] 交叉引用(至少 2 个出站链接)

更新已有页面:

Agent 不只是"追加新内容",而是:

  • 检查新内容和已有内容的冲突
  • 如果冲突,标注两个版本的来源和日期
  • 如果互补,插入到对应段落
  • 更新 frontmatter 的 updated 日期和 sources 列表
  • 保持段落结构不变------不重写已有内容

Phase 6:交叉引用与回链

建页和更新完成后,Agent 执行最后一轮操作:backlink 同步。

新页面已经链了已有页面。但已有页面还没链回新页面。Agent 扫描新页面涉及的标签和关键词,在已有页面中搜索------找到 8 个已有页面需要加回链。然后逐一添加 [[新页面]] 引用。

最后更新 index.md、记录 log.md、输出变化报告。


Phase 4 深度拆解:决策不是"看一眼就定"

164 个候选主题的决策不是 Agent 一个个点过去的选择题。它有一个完整的决策流程:

第 1 步:聚合。 37 个芯片/传感器名称中,多个是同义词或变体------"Hi3519" "Hi3519DV500" "HI3519" 指同一个芯片。Agent 先做名称归一化,37 个候选合并为 8 个实体候选。

第 2 步:去重。 127 个技术概念中,约 30% 是同一个概念的不同表述------"启动流程" "boot sequence" "系统启动" "上电启动"。Agent 用 TF-IDF 相似度聚类,合并为约 40 个概念候选。

第 3 步:查已有页面。 Agent 不盲目建页------先搜索 Wiki 中是否已有类似页面。40 个概念候选中,25 个已有对应页面(或部分覆盖),只需更新不需建页。

第 4 步:阈值过滤。 剩下约 15 个真正的新概念候选。Agent 逐条检查来源数量------出现在 2+ 个来源中的直接建页,只出现在 1 个来源但信息量 > 500 字的考虑建页,其余跳过。

最终产出: 8 个实体候选 → 3 个建页(Hi3516DV500、ToolPlatform、SVP NPU)+ 15 个概念候选 → 7 个建页(裸烧升级、U-Boot 移植...)+ 约 40 个已有页面 → 25 个更新。跳过的 ~133 个候选也不是"浪费"------它们的核心信息被嵌入了对应的已有页面中,没有丢失。


决策失败的三种模式

模式一:过度建页。 如果阈值设为"所有概念都建页",40 个概念全建------结果是一堆"只有 3 句话"的僵尸页,被引用 0 次,占用搜索索引但不提供实质价值。

模式二:过度保守。 如果阈值设为"只有用户明确要求的才建",89 份 PDF 只更新 3 个已有页面------大量有价值的知识沉在 raw/ 里永远变成"暗知识"。

模式三:重复建页。 Agent 没查到已有页面就建了新的。结果 Wiki 里同时存在"MPP 媒体处理"和"媒体处理流水线"两个页面------内容 80% 重复。这需要更严格的"建页前搜索"和更宽松的"部分覆盖 → 更新而非新建"策略。

避免模式三的机制: 建页前,Agent 必须执行一次全 Wiki 的关键词搜索(不是只看 index.md)。搜索范围包括已有的页面标题、frontmatter tags 和正文关键词。只有搜索结果为空时才进入建页流程。


不同来源类型的处理差异

PDF 来源: 需要 Phase 1-2 的完整处理(分类 + 文本提取)。PDF 的信息密度通常高于纯文本------一份 19 页的 PDF 可能比一篇 2000 字的博客包含更多结构化知识。

纯文本/Markdown 来源: 跳过 Phase 1-2,直接进入 Phase 3 内容理解。速度快 3-5 倍。

URL 来源: Agent 先抓取网页内容转 Markdown,保存到 raw/articles/。URL 来源的可靠性差异很大------官方文档 > 技术社区 > 个人博客。Agent 不判断来源可靠性,但会标记来源 URL 让读者自己判断。

对话/聊天记录来源: 用户说"把今天的调试经验收进 Wiki"。Agent 读取飞书聊天记录(通过 session_search),提取技术讨论,去掉闲聊,按主题分配到已有的概念页面。这是 Wiki 最轻量的摄入方式------没有新页面创建,只有对已有页面的增量补充。

为什么是 6 阶段,不是 3 阶段

你可能会问:为什么不简化------"读到→理解→写"三步就完了?

因为 PDF 知识摄入最大的坑不是"读不懂",而是"写乱了"。如果没有 Phase 1 的文件分类,Agent 不会知道硬件类和软件类文档的区别------硬件类更可能建 entity 页、软件类更可能建 concept 页。如果没有 Phase 4 的批量决策,Agent 会为 164 个候选全部建页------3 个月后 Wiki 爆炸。

6 个阶段不是多余的------每一个阶段都在防止一种特定的失败模式。

失败模式与对应防御阶段:

  • 文件散乱、无法搜索 → Phase 1 结构化归档
  • PDF 表格提取错误、信息丢失 → Phase 2 pymupdf + X 坐标聚类
  • Agent 不了解整体结构、盲目建页 → Phase 3 先读索引后读正文
  • 为每个候选主题建页、Wiki 爆炸 → Phase 4 阈值过滤 + 批量决策
  • 页面格式不统一、信息碎片化 → Phase 5 模板化生成 + 标准化 frontmatter
  • 新建页面孤立、已有页面没回链 → Phase 6 backlink 同步

每个阶段解决一个特定问题。缺任何一个,Wiki 质量都在对应维度上打折。


不同场景的流水线适配

完整 6 阶段流水线是为 PDF 批量摄入设计的。但实际使用中,大部分摄入都是轻量的。

轻量摄入(飞书聊天记录): 跳过 Phase 1-2(没有 PDF),Phase 3 简化为读聊天上下文,Phase 4 简化为"更新已有页面",Phase 5 简化为追加段落,Phase 6 正常执行。全过程 30 秒。

URL 来源: Phase 1 改为网页抓取 + 转 Markdown,Phase 2 跳过(已经是纯文本),Phase 3-6 正常。全过程 1-2 分钟。

单文件 Markdown: Phase 1-2 全部跳过,直接进入 Phase 3。全过程 15 秒。

批量 PDF(89 份): 完整 6 阶段,全过程 75 分钟。最耗时的是 Phase 2 的 PDF 提取(每份 PDF 3-15 秒)和 Phase 4 的决策(164 个候选)。