|
|
@@ -0,0 +1,360 @@
|
|
|
+# 如何将他人文档整理为 LLM Wiki 笔记
|
|
|
+
|
|
|
+> 以 STM32 学习笔记为例,总结从多源文档到结构化 Wiki 的完整流程。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 1. 源材料分析
|
|
|
+
|
|
|
+### 1.1 识别源类型
|
|
|
+
|
|
|
+| 类型 | 处理方式 | 工具 |
|
|
|
+|------|---------|------|
|
|
|
+| DOCX 教程 | `pandoc` 转 MD,提取图片 | pandoc + --extract-media |
|
|
|
+| PDF 手册 | `markitdown` 或直接 OCR | markitdown skill |
|
|
|
+| 视频教程 | 已有配套讲义则直接处理,无讲义需先转录 | — |
|
|
|
+| 网页/博客 | `webfetch` 抓取 | webfetch tool |
|
|
|
+
|
|
|
+### 1.2 评估教学内容
|
|
|
+
|
|
|
+拿到文档后先扫描目录结构,理解其教学法:
|
|
|
+
|
|
|
+- 按什么顺序讲解?(外设逐个?还是功能分类?)
|
|
|
+- 代码风格是什么?(寄存器?标准库?HAL?)
|
|
|
+- 有什么独特的教学方法?(例如尚硅谷的"三步进化法":裸地址 → 结构体 → 位宏定义)
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 2. 文档转换与图片提取
|
|
|
+
|
|
|
+### 2.1 DOCX → Markdown
|
|
|
+
|
|
|
+```powershell
|
|
|
+# 提取到 temp 目录,保留所有图片
|
|
|
+pandoc "源文档.docx" -t markdown --wrap=none `
|
|
|
+ --extract-media="C:\temp\docx_media" `
|
|
|
+ -o "C:\temp\docx_media\笔记.md"
|
|
|
+```
|
|
|
+
|
|
|
+这会生成:
|
|
|
+- `.md` 文件(含图片引用路径)
|
|
|
+- `media/` 目录(含所有 PNG、EMF 等图片)
|
|
|
+
|
|
|
+### 2.2 阅读并理解转换后的文档
|
|
|
+
|
|
|
+用 Read tool 逐段阅读 MD 文件,在 read 时注意:
|
|
|
+
|
|
|
+- **图片上下文**:每张图片前后文字说明该图片内容
|
|
|
+- **章节结构**:编号标题(1.、1.1、2.等)反映原文档组织方式
|
|
|
+- **代码块**:注意代码风格和教学顺序
|
|
|
+
|
|
|
+```markdown
|
|
|
+# 读取文档的前 200 行了解结构
|
|
|
+Read offset=1 limit=200
|
|
|
+
|
|
|
+# 跳读找到关键章节
|
|
|
+Read offset=N limit=50
|
|
|
+```
|
|
|
+
|
|
|
+### 2.3 图片筛选(核心步骤)
|
|
|
+
|
|
|
+**不要盲目全部复制到仓库!** 大多数 DOCX 图片是 IDE 截图、安装步骤图等无长期参考价值的内容。
|
|
|
+
|
|
|
+筛选策略:
|
|
|
+
|
|
|
+1. **用 API 视觉模型逐张验证**(可调用兼容 OpenAI API 的 VLM)
|
|
|
+
|
|
|
+```powershell
|
|
|
+# 调用视觉 API 识别图片内容
|
|
|
+$b64 = [Convert]::ToBase64String([IO.File]::ReadAllBytes($path))
|
|
|
+$body = @{
|
|
|
+ model = "qwen3.5-9b-uncensored-nothink" # 非推理模型,content 直接出结果
|
|
|
+ messages = @(@{ role = "user"; content = @(
|
|
|
+ @{ type = "text"; text = "图中内容是什么?用一句话回答" }
|
|
|
+ @{ type = "image_url"; image_url = @{ url = "data:image/png;base64,$b64" } }
|
|
|
+ )})
|
|
|
+ max_tokens = 100
|
|
|
+}
|
|
|
+$r = Invoke-RestMethod -Uri "https://api.example.com/v1/chat/completions" ...
|
|
|
+$r.choices[0].message.content
|
|
|
+```
|
|
|
+
|
|
|
+2. **只保留以下类型图片**:
|
|
|
+ - 寄存器位域图(Register bit-field diagram)
|
|
|
+ - 外设框图(Peripheral block diagram)
|
|
|
+ - 时序图(Timing diagram)
|
|
|
+ - 电路原理图(Schematic)
|
|
|
+ - 协议帧格式图(Protocol frame format)
|
|
|
+
|
|
|
+3. **删除以下类型**:
|
|
|
+ - IDE 安装/配置截图(Keil, CubeMX, VS Code)
|
|
|
+ - 项目创建步骤截图
|
|
|
+ - 驱动安装截图
|
|
|
+ - 内存映射表(Memory map)
|
|
|
+ - 2x2 像素小图标
|
|
|
+
|
|
|
+4. **重命名**:`image1.png` → `rcc_register_description.png`
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 3. 笔记架构设计
|
|
|
+
|
|
|
+### 3.1 目录结构
|
|
|
+
|
|
|
+```
|
|
|
+raw/{source-category}/
|
|
|
+ {topic}/ # 每个主题一个目录
|
|
|
+ 01-第一篇章.md
|
|
|
+ 02-第二篇章.md
|
|
|
+ assets/ # 该主题的图片资源
|
|
|
+ gpio_pin_structure.png
|
|
|
+ usart_block.png
|
|
|
+```
|
|
|
+
|
|
|
+### 3.2 笔记粒度
|
|
|
+
|
|
|
+| 粒度 | 适用场景 | 示例 |
|
|
|
+|------|---------|------|
|
|
|
+| 单篇完整笔记 | 内容单一的文档 | `01-环境搭建与工程模板.md` |
|
|
|
+| 分篇笔记 | 内容多的文档,按外设拆分 | `02-GPIO详解.md` ~ `17-FSMC与LCD显示.md` |
|
|
|
+
|
|
|
+### 3.3 多源融合策略
|
|
|
+
|
|
|
+当有多个教程源(寄存器教程 + 标准库教程 + HAL 教程)时:
|
|
|
+
|
|
|
+```
|
|
|
+# 在每个笔记中按"三层代码"结构组织
|
|
|
+## 寄存器方式(尚硅谷风格)
|
|
|
+~~~c
|
|
|
+// 裸地址操作 → 结构体宏定义
|
|
|
+RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;
|
|
|
+~~~
|
|
|
+
|
|
|
+## 标准库方式(江协科技风格)
|
|
|
+~~~c
|
|
|
+RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
|
|
|
+~~~
|
|
|
+
|
|
|
+## HAL 库方式
|
|
|
+~~~c
|
|
|
+HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET);
|
|
|
+~~~
|
|
|
+```
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 4. 讲解正文撰写规范
|
|
|
+
|
|
|
+### 4.1 每个外设笔记应包含
|
|
|
+
|
|
|
+1. **基本概念**:该外设是什么、有什么用
|
|
|
+2. **工作原理**:结合框图/时序图讲解
|
|
|
+3. **寄存器详解**:关键寄存器位域说明(表格形式)
|
|
|
+4. **代码实战**:三层代码 + 逐行注释
|
|
|
+5. **核心函数速查**:表格汇总
|
|
|
+
|
|
|
+### 4.2 位操作注释规范
|
|
|
+
|
|
|
+寄存器操作的每行代码必须标注操作符含义:
|
|
|
+
|
|
|
+```c
|
|
|
+REG |= BITMASK; // |= 按位或: 保持其他位不变,只将目标位置1
|
|
|
+REG &= ~BITMASK; // &= ~ 按位与+取反: 保留其他位,只将目标位清0
|
|
|
+REG ^= BITMASK; // ^= 按位异或: 翻转目标位
|
|
|
+x << N; // << 左移N位
|
|
|
+~x; // ~ 按位取反
|
|
|
+REG & BITMASK // & 按位与: 测试特定位是否为1
|
|
|
+while (条件); // 轮询等待硬件标志位
|
|
|
+```
|
|
|
+
|
|
|
+示例:
|
|
|
+
|
|
|
+```c
|
|
|
+// 使能 GPIOD 时钟(APB2ENR 寄存器第 5 位置 1)
|
|
|
+RCC->APB2ENR |= RCC_APB2ENR_IOPDEN; // |= 按位或: 保持其他时钟位不变
|
|
|
+ // 只将 IOPDEN(IOPD 时钟使能位) 置 1
|
|
|
+
|
|
|
+// 配置 PD13 为推挽输出 50MHz
|
|
|
+GPIOD->CRH &= ~GPIO_CRH_CNF13; // &= ~ 按位与+取反: 清除 CNF13 位域
|
|
|
+GPIOD->CRH |= GPIO_CRH_MODE13; // |= 按位或: 设置 MODE13=11 (50MHz)
|
|
|
+ // MODE[1:0]=11 + CNF[1:0]=00
|
|
|
+ // = 推挽输出、最高速度
|
|
|
+```
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 5. 图片管理
|
|
|
+
|
|
|
+### 5.1 获取图片
|
|
|
+
|
|
|
+```powershell
|
|
|
+# pandoc 提取
|
|
|
+pandoc source.docx --extract-media=./media -o output.md
|
|
|
+
|
|
|
+# 或手动复制(如果已有图片文件)
|
|
|
+Copy-Item source/*.png assets/
|
|
|
+```
|
|
|
+
|
|
|
+### 5.2 大图压缩后再传 API
|
|
|
+
|
|
|
+> **问题**:pandoc 提取的 PNG 经常 >200KB(最大可达 1.7MB),直接 base64 传入视觉 API 会导致超时(connection timeout 或空响应)。
|
|
|
+>
|
|
|
+> **解决**:先压缩到宽度 800px、质量 80%,体积可缩小 10~50 倍。
|
|
|
+
|
|
|
+```powershell
|
|
|
+# 压缩图片到 800px 宽、质量 80%,存入 temp
|
|
|
+Add-Type -AssemblyName System.Drawing
|
|
|
+
|
|
|
+function Compress-Image {
|
|
|
+ param($srcPath, $destPath, $maxWidth = 800, $quality = 80)
|
|
|
+ $img = [System.Drawing.Image]::FromFile($srcPath)
|
|
|
+ $ratio = [Math]::Min(1.0, $maxWidth / $img.Width)
|
|
|
+ $w = [int]($img.Width * $ratio)
|
|
|
+ $h = [int]($img.Height * $ratio)
|
|
|
+ $bmp = New-Object System.Drawing.Bitmap($w, $h)
|
|
|
+ $g = [System.Drawing.Graphics]::FromImage($bmp)
|
|
|
+ $g.DrawImage($img, 0, 0, $w, $h)
|
|
|
+ $g.Dispose()
|
|
|
+ $encParams = New-Object System.Drawing.Imaging.EncoderParameters(1)
|
|
|
+ $encParams.Param[0] = New-Object System.Drawing.Imaging.EncoderParameter(
|
|
|
+ [System.Drawing.Imaging.Encoder]::Quality, [int64]$quality)
|
|
|
+ $codec = [System.Drawing.Imaging.ImageCodecInfo]::GetImageEncoders() |
|
|
|
+ Where-Object { $_.MimeType -eq 'image/jpeg' }
|
|
|
+ $bmp.Save($destPath, $codec, $encParams)
|
|
|
+ $bmp.Dispose(); $img.Dispose()
|
|
|
+}
|
|
|
+
|
|
|
+# 使用示例:压缩原图后传给 API 验证
|
|
|
+Compress-Image "原始大图.png" "C:\temp\压缩小图.jpg" 800 80
|
|
|
+```
|
|
|
+
|
|
|
+### 5.3 验证与筛选
|
|
|
+
|
|
|
+压缩后调用视觉 API 验证每张图片是否与其文件名匹配:
|
|
|
+
|
|
|
+```powershell
|
|
|
+function Test-Img {
|
|
|
+ param($path, $question)
|
|
|
+ # 大图先压缩
|
|
|
+ if ((Get-Item $path).Length -gt 150KB) {
|
|
|
+ $compressed = Join-Path $env:TEMP "tmp_$(Get-Random).jpg"
|
|
|
+ Compress-Image $path $compressed 800 80
|
|
|
+ $sendPath = $compressed
|
|
|
+ } else {
|
|
|
+ $sendPath = $path
|
|
|
+ }
|
|
|
+ $b64 = [Convert]::ToBase64String([IO.File]::ReadAllBytes($sendPath))
|
|
|
+ $body = @{ model = "qwen3.5-9b-uncensored-nothink"
|
|
|
+ messages = @(@{ role = "user"; content = @(
|
|
|
+ @{ type = "text"; text = $question }
|
|
|
+ @{ type = "image_url"; image_url = @{ url = "data:image/jpeg;base64,$b64" } }
|
|
|
+ )})
|
|
|
+ max_tokens = 60 } | ConvertTo-Json -Depth 10
|
|
|
+ $r = Invoke-RestMethod -Uri "https://api.1808366.xyz/v1/chat/completions" ...
|
|
|
+ if ($compressed) { Remove-Item $compressed -Force }
|
|
|
+ return $r.choices[0].message.content
|
|
|
+}
|
|
|
+
|
|
|
+foreach ($f in $allImages) {
|
|
|
+ $result = Test-Img $f "图中内容是什么?一句话回答"
|
|
|
+ if ($result -match "超时|空|null") { Write-Warning "$f 仍需手动检查" }
|
|
|
+ Write-Host "$f => $result"
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+### 5.4 常见图片尺寸参考
|
|
|
+
|
|
|
+| 图片宽度 | 高度 | 文件大小 | 典型内容 | 是否需要压缩 |
|
|
|
+|---------|------|---------|---------|------------|
|
|
|
+| 960×154 | 窄长 | ~43KB | 寄存器位域图 | 否 |
|
|
|
+| 700×250 | 适中 | ~14KB | 小结构图 | 否 |
|
|
|
+| 2500×1500 | 大 | ~260KB | 完整框图 | 是 |
|
|
|
+| 1200×1700 | 大 | ~400KB | 波形图 | 是 |
|
|
|
+| 1800×1600 | 大 | ~1.7MB | 复杂框图 | 必须压缩 |
|
|
|
+
|
|
|
+### 5.5 命名约定
|
|
|
+
|
|
|
+- 全部小写英文
|
|
|
+- 蛇形命名(snake_case)
|
|
|
+- 前缀表示所属:`{外设}_{内容}.png`
|
|
|
+- 如:`gpio_pin_structure.png`, `usart_block_diagram.png`, `i2c_start_stop.png`
|
|
|
+
|
|
|
+### 5.6 引用
|
|
|
+
|
|
|
+在笔记中使用相对路径引用:
|
|
|
+
|
|
|
+```markdown
|
|
|
+
|
|
|
+*来源:STM32 参考手册*
|
|
|
+```
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 6. 仓库提交规范
|
|
|
+
|
|
|
+### 6.1 提交类型
|
|
|
+
|
|
|
+| 前缀 | 场景 |
|
|
|
+|------|------|
|
|
|
+| `ingest` | 导入新资料 + 同步更新 wiki |
|
|
|
+| `wiki` | 纯知识页整理(不伴随导入) |
|
|
|
+| `raw` | 仅涉及原始资料资产,不改 wiki |
|
|
|
+| `lint` | 知识库健康检查与修复 |
|
|
|
+| `docs` | 仓库说明文档与协作规则更新 |
|
|
|
+
|
|
|
+### 6.2 每次 ingest 必须
|
|
|
+
|
|
|
+1. 创建或更新 `wiki/index.md`
|
|
|
+2. 追加 `wiki/log.md`
|
|
|
+3. 最终提交使用 `ingest: 简短摘要`
|
|
|
+
|
|
|
+### 6.3 每次操作后
|
|
|
+
|
|
|
+```powershell
|
|
|
+git add .
|
|
|
+git commit -m "<类型>: <摘要>"
|
|
|
+```
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 7. 大文件与图片处理策略
|
|
|
+
|
|
|
+### 7.1 仓库 vs Temp
|
|
|
+
|
|
|
+| 位置 | 用途 |
|
|
|
+|------|------|
|
|
|
+| `assets/` | 最终选定的高质量图片(精选后≤50张) |
|
|
|
+| `C:\Users\<你>\AppData\Local\Temp\opencode\` | 原始提取的全部图片(按需保留) |
|
|
|
+
|
|
|
+### 7.2 不提交的文件
|
|
|
+
|
|
|
+- EMF 格式图片(矢量图,Markdown 不直接支持)
|
|
|
+- IDE 安装/配置截图
|
|
|
+- 2x2 像素小图标
|
|
|
+- 超过 1MB 的非必要大图
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 8. 完整工作流速查
|
|
|
+
|
|
|
+```mermaid
|
|
|
+flowchart TD
|
|
|
+ A[拿到源文档 DOCX/PDF/网页] --> B[pandoc 转 MD + 提取图片]
|
|
|
+ B --> C[阅读 MD 理解教学结构与风格]
|
|
|
+ C --> D[设计笔记架构<br/>拆分外设/概念]
|
|
|
+ D --> E[撰写讲解正文<br/>三层代码 + 位操作注释]
|
|
|
+ E --> F[API 视觉模型验证图片]
|
|
|
+ F --> G[精选+重命名图片到 assets/]
|
|
|
+ G --> H[更新 wiki/index.md + log.md]
|
|
|
+ H --> I[git commit<br/>ingest/raw/wiki]
|
|
|
+```
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 9. 注意事项
|
|
|
+
|
|
|
+1. **不要覆盖原始文档** — `raw/` 目录只读不改
|
|
|
+2. **不要全部图片都提交** — 精选有用的,其余放 temp
|
|
|
+3. **不要猜测图片内容** — 用 API 视觉模型验证
|
|
|
+4. **不要省略位操作注释** — 每行 `|=`、`&=~`、`<<` 都要解释
|
|
|
+5. **不要混用提交意图** — 一次提交只做一件事
|