Research Hub — 统一研究处理与自学习系统
> 定位:统一的智能信息提取、结构化分析与自迭代系统。视频 + 文本双管线内置,输出遵循 zotero-note-template 五模块模板。知识库根目录 E:/知识库/。
⛔ 开始任何任务前,先跳到底部阅读「九、关键约束」
🔍 检查未完成接续任务
cat "E:/知识库/01-学习日志 规则/pending_tasks.json" 2>/dev/null && python -c "
import json
with open('E:/知识库/01-学习日志 规则/pending_tasks.json') as f: d=json.load(f)
if d.get('status')=='transcribed':
print(f'⚠️ 待接续: {d[\"title\"]} | 转写完成 {d[\"completed_at\"]} | 下一步: {d[\"next_step\"]}')
" || echo "无待接续"
⛔ 强制自检(任何情况下不可跳过)
写完任何一篇分析 .md 后,下一条工具调用必须是以下三条 Bash 命令——不可先做下一件事、不可跳过、不可"之后统一验收"。
# 1. 字节数检查(标准≥10000,黄线≥8000)
wc -c "刚写完的.md文件路径"
# 2. 模块数检查(要求≥5 — zotero-note-template 五模块)
grep -c '^## ' "刚写完的.md文件路径"
# 3. 八维度检查
for dim in "研究/领域/" "研究/方法/" "研究/技术/" "研究/尺度/" "研究/主题/" "研究/理论/" "来源/类型/" "学习/"; do
count=$(grep -c "$dim" "刚写完的.md文件路径")
[ "$count" -eq 0 ] && echo "❌ 缺失维度: $dim"
done
任何一条不通过 → 立刻补充内容,补充后再自检,直到全部通过。通过后才允许处理下一篇。
> ⚠️ 踩坑提醒(2026-08-06 实测):
> 1. bash grep 匹配 📎 这类 emoji 会因编码误报为 0(文件里明明有却说没有)——凡涉及 emoji 字段的检查(如 📎 原文链接),改用 Python 复核:python -c "print('📎 原文链接' in open('文件').read())"。
> 2. 标签白名单比对:tags_taxonomy.txt 条目带 # 前缀(如 #研究/领域/城乡规划),解析时必须先 strip() 掉 # 再比对,否则会误判全部标签违规。
> 📎 来源链接检查:每篇末尾必须包含 📎 原文链接: 字段。视频标注原始 URL,公众号标注文章链接,本地文件标注文件路径。
分析完成后清除状态标记:
echo '{}' > "E:/知识库/01-学习日志 规则/pending_tasks.json"
⛔ 五篇重置:每完成一篇分析并自检通过后,运行:
python scripts/track_progress.py --increment --file "刚写完的 .md 路径"
--increment 内置了质量门禁:必须先通过自检(字节+模块+维度+链接)才允许 +1。自检未通过 → 阻塞请求,拒绝计数。
同时内置五篇检查:达到 5 的倍数时自动提醒重读质量标准。
⛔ 标签强制合规(任何情况下不可跳过)
规则1:只用白名单标签
所有 tags 必须来自 references/tags_taxonomy.txt。
规则2:七维度必覆盖
| 维度 | 前缀 | 示例 |
|---|---|---|
| 研究领域 | 研究/领域/ |
城市设计、城乡规划、交通规划、城市更新 |
| 研究方法 | 研究/方法/ |
定量分析、案例研究、GIS分析、空间计量 |
| 技术方向 | 研究/技术/ |
人工智能、数字孪生、参数化设计、智慧城市 |
| 空间尺度 | 研究/尺度/ |
区域、城市、街区、社区、公共空间 |
| 政策主题 | 研究/主题/ |
城市更新、双碳、韧性城市、空间治理 |
| 理论框架 | 研究/理论/ |
人机交互、空间生产、协同规划、城市形态学 |
| 来源/事件 | 来源/类型/ 来源/期刊/ |
期刊论文、公众号文章、政策文件、城市规划 |
| 学习 | 学习/ |
考研笔记、课程笔记、读书笔记 |
规则3:写完即刻验证
见顶部"⛔ 强制自检"中第三条 Bash 命令。
规则4:Zotero 笔记双标签制
Zotero 来源的论文笔记采用双字段:
- tags: → 白名单标签(统一可检索,7 维度必覆盖)
- keywords: → 保留原文关键词(不丢失语义,自学习候选源)
公众号/视频来源的笔记只用 tags:,不需要 keywords:。
规则5:frontmatter 结构规范(Obsidian 属性显示依赖此)
字段顺序固定,不得颠倒、不得缺省:
---
title: "标题" # 必填,来自正文 # 标题
author: "作者(机构)" # 有则填
date: 2026-08-06 # 必填,YYYY-MM-DD 或 YYYY-MM
type: 公众号文章 # 必填:公众号文章/视频分析/期刊论文
journal: "《期刊名》" # 学术来源有则填
tags: # 必填,白名单,7 维度各 ≥1
- 研究/领域/...
source: "..." # 可选,保留原文出处
---
引号铁律:frontmatter 值内需要引号时必须用中文弯引号「""」,禁止 ASCII 直引号嵌套——title: "含"内嵌"引号" 会导致 YAML 解析中断、Obsidian 属性消失。
Zotero 来源字段(02-论文阅读)另有:Title Author Year Publication Citekey DOI ZoteroKey + keywords:,顺序:Title → Author → Year → Date → Publication → Citekey → DOI → ZoteroKey → Rate → tags → keywords → aliases。
执行契约
- "写完"的定义:Write 工具调用返回成功。
- 写完后立即跟 Bash 自检,两者之间不允许插入任何其他文件操作。
- 批量场景下同样适用:每篇写完→自检→下一篇,不能积攒到末尾一次性验证。
一、系统架构
用户输入(链接 / 文件 / 反馈)
│
▼
┌─ Phase 1: 智能路由 ──────────────────────────┐
│ 自动识别 → 视频? / 公众号? / 文件? / 反馈? │
└──────────┬───────────────────────────────────┘
│
┌──────┴──────────────┐
▼ ▼
┌─ Phase 2: 视频管线 ──┐ ┌─ Phase 2: 文本管线 ──┐
│ 下载→音频→转写→ │ │ WebFetch→保存→分析 │
│ 关键帧→分析→自检 │ │ →自检 │
└──────────┬───────────┘ └──────────┬───────────┘
│ │
└──────────┬─────────────┘
▼
统一五模块模板输出(zotero-note-template)
→ E:/知识库/
│
▼
┌─ Phase 3: 自学习 ────────────────────────────┐
│ 检查触发 → 扫描DB → 提取模式 → 报告 → 确认 │
│ → 更新框架 → 同步标签/词典/质量线 │
└──────────────────────────────────────────────┘
二、Phase 1:智能路由
2.1 输入检测
| 输入特征 | 类型 | 管线 | 置信度 |
|---|---|---|---|
URL 含 bilibili.com/video/ b23.tv |
视频 | 视频管线 | ≥0.95 |
URL 含 youtube.com/watch youtu.be |
视频 | 视频管线 | ≥0.95 |
URL 含 mp.weixin.qq.com/s/ |
公众号 | 文本管线 | ≥0.99 |
本地 .mp4 .mkv .webm .flv |
视频文件 | 视频管线(跳过下载) | ≥0.95 |
本地 .m4a .wav .mp3 |
音频文件 | 视频管线(直接转写) | ≥0.95 |
本地 .txt .md |
文本文件 | 文本管线(直接分析,存入05-其它来源) | ≥0.85 |
@framework: 开头 |
框架反馈 | Phase 3 反馈处理 | 0.99 |
| 其他 URL | 未知 | WebFetch 探测后确认 | <0.95 |
执行:python scripts/detect_source.py "<输入>"
2.2 去重检查(视频)
视频路由前提取 BV 号/视频 ID,检查数据库是否有已有报告:
BV_ID=$(echo "$URL" | grep -oP 'BV\w+')
grep -rl "$BV_ID" "E:/知识库/03-视频来源/" 2>/dev/null
- 已有达标报告 → 提示"已处理过,是否重跑?"
- 已有未达标报告 → 提示"已有不达标,建议重跑"
- 无报告 → 正常处理
2.3 批量处理
多条输入时:逐条检测→分组(视频/文本)→确认→先文本后视频→每篇独立自检→全部完成后触发 Phase 3。
三、Phase 2A:视频管线
Step 1:视频下载
B站:
yt-dlp -f "bestvideo[ext=mp4]+bestaudio[ext=m4a]" -o "output_%(id)s.%(ext)s" "<URL>"
# 若合并失败,手动分片后用 imageio_ffmpeg 合并
# ⚠️ B站需禁用代理:http_proxy="" https_proxy="" no_proxy="*" yt-dlp ...
YouTube:
yt-dlp -f "bestvideo[ext=mp4]+bestaudio[ext=m4a]" -o "%(title)s.%(ext)s" "<URL>"
Step 2:音频提取
FFMPEG=$(python -c "import imageio_ffmpeg; print(imageio_ffmpeg.get_ffmpeg_exe())")
"$FFMPEG" -i "video.mp4" -i "audio.m4a" -c copy "merged.mp4" -y
"$FFMPEG" -i "merged.mp4" -vn -acodec pcm_s16le -ar 16000 -ac 1 "audio.wav" -y
Step 3:语音转写
3.0 转写前自检(⚠️ 强制,不可跳过)
python -c "
import os, sys
from pathlib import Path
print('=== 转写前自检 ===')
issues = []
# 1. 音频文件检查 + 时长估算
audio = Path('audio.wav')
if not audio.exists():
print('❌ 致命:audio.wav 不存在'); sys.exit(1)
# 时长估算:16kHz 16bit mono = 32000 bytes/sec
size_mb = audio.stat().st_size / 1e6
dur_min = audio.stat().st_size / 32000 / 60
print(f'音频: {size_mb:.0f}MB | 约 {dur_min:.0f}分钟')
# 2. 依赖检查(⚠️ 依赖链必须完整:faster-whisper 与 torch 必须在同一 Python 环境)
try:
from faster_whisper import WhisperModel
print('✅ faster-whisper 可用')
except ImportError:
issues.append('❌ 致命:faster-whisper 未安装')
issues.append(' 修复:python -m pip install faster-whisper torch -i https://pypi.tuna.tsinghua.edu.cn/simple')
try:
import torch
cuda = torch.cuda.is_available()
print(f\"{'✅ GPU CUDA' if cuda else 'ℹ️ CPU INT8(本机无 GPU,属正常配置,速度约1.5x实时)'}\")
except ImportError:
issues.append('❌ 致命:torch 未安装(faster-whisper 依赖它,缺失会导致转写直接失败)')
issues.append(' 修复:python -m pip install torch -i https://pypi.tuna.tsinghua.edu.cn/simple')
# 3. 模型检查
model_found = False
for p in [Path.home() / '.cache/modelscope/models/Systran--faster-whisper-medium/snapshots/master',
Path.home() / '.cache/faster-whisper-medium']:
if (p / 'model.bin').exists():
print(f'✅ 本地模型: {p}')
model_found = True
break
if not model_found:
issues.append('⚠️ 无本地模型,将自动下载 medium(约 1.5GB)')
# 4. 磁盘空间
import shutil
free_gb = shutil.disk_usage('.').free / 1e9
print(f'磁盘剩余: {free_gb:.1f}GB')
if free_gb < 2:
issues.append(f'❌ 致命:磁盘空间不足({free_gb:.1f}GB < 2GB)')
# 5. 时长预估
speed = 6.0 if cuda else 1.5 # 倍速:GPU约6倍实时,CPU约1.5倍
est_sec = dur / speed + 15 # +15秒模型加载
print(f'预估转写时间: {est_sec/60:.1f}分钟({'GPU' if cuda else 'CPU'} {speed}x实时 + 模型加载)')
# 总结
if issues:
print('\\n⚠️ 发现问题:')
for i in issues:
print(f' {i}')
if any('致命' in i for i in issues):
print('\\n❌ 存在致命问题,无法继续。请修复后重试。')
sys.exit(1)
else:
print('\\n⚠️ 存在警告,但仍可继续。')
else:
print('\\n✅ 自检通过,可以开始转写')
"
3.1 执行转写
唯一方案:faster-whisper(本机无 GPU 时为 CPU INT8,属正常配置,勿等 GPU;若环境检测到 CUDA 则自动用 GPU)。
python -c "
import torch
from faster_whisper import WhisperModel
from pathlib import Path
# ── 设备检测 ──
device = 'cuda' if torch.cuda.is_available() else 'cpu'
compute = 'float16' if device == 'cuda' else 'int8'
# ── 模型查找 ──
model_path = None
for c in [Path.home() / '.cache/modelscope/models/Systran--faster-whisper-medium/snapshots/master',
Path.home() / '.cache/faster-whisper-medium']:
if (c / 'model.bin').exists(): model_path = str(c); break
if not model_path: model_path = 'medium'
print(f'Device: {device} | Compute: {compute} | Model: {model_path}')
model = WhisperModel(model_path, device=device, compute_type=compute)
# ── 语言检测(前30秒)──
_, probe_info = model.transcribe('audio.wav', language=None, beam_size=1, vad_filter=True)
lang = 'en' if probe_info.language == 'en' and probe_info.language_probability > 0.8 else 'zh'
print(f'Language: {probe_info.language} -> {lang}')
# ── 转写(优化参数:beam_size=5, temperature=0.0, repetition_penalty=1.1)──
segments, info = model.transcribe(
'audio.wav',
language=lang,
beam_size=5, # 提升术语一致性
temperature=0.0, # 确定性输出,不随机采样
repetition_penalty=1.1, # 抑制重复循环
vad_filter=True,
vad_parameters=dict(
min_silence_duration_ms=500,
threshold=0.4,
),
)
# ── 写入并去重 ──
lines = []
for seg in segments:
text = seg.text.strip()
if text and (not lines or text != lines[-1]): # 去重:连续相同行只保留一次
lines.append((seg.start, seg.end, text))
# ── 术语后处理 ──
dict_path = Path('references/terminology_dict.txt')
if dict_path.exists():
with open(dict_path, 'r', encoding='utf-8') as d:
for line in d:
line = line.strip()
if '→' in line and not line.startswith('#'):
wrong, correct = line.split('→', 1)
for i in range(len(lines)):
start, end, text = lines[i]
lines[i] = (start, end, text.replace(wrong.strip(), correct.strip()))
print(f'Terminology post-processing applied')
# ── 输出 ──
with open('output/transcript.srt', 'w', encoding='utf-8') as srt, \\
open('output/transcript.txt', 'w', encoding='utf-8') as txt:
for i, (start, end, text) in enumerate(lines, 1):
srt.write(f'{i}\\\n{start:.3f} --> {end:.3f}\\\n{text}\\\n\\\n')
txt.write(text + '\\\n')
print(f'Done: {len(lines)} segments')
"
参数说明:
| 参数 | 值 | 作用 |
|------|-----|------|
| beam_size | 5 | 搜索 5 条候选路径,术语一致性显著提升 |
| temperature | 0.0 | 确定性输出,同段音频每次转写结果一致 |
| repetition_penalty | 1.1 | 抑制模型陷入重复循环 |
| min_silence_duration_ms | 500 | 500ms 以上静音才切段,减少碎句 |
| 去重 | 连续相同行去重 | 防止模型卡住时输出重复内容 |
术语后处理:转写完成后自动读取 references/terminology_dict.txt,逐条替换常见音误。
⛔ 转写完成后立即写状态标记(防session断开丢失):
python -c "
import json, datetime
json.dump({
'video_id': 'BV_ID', 'title': '视频标题',
'status': 'transcribed',
'transcript': 'output/transcript.txt',
'completed_at': datetime.datetime.now().isoformat(),
'next_step': 'segmented_analysis' if 转写字数 > 8000 else 'direct_analysis'
}, open('E:/知识库/01-学习日志 规则/pending_tasks.json', 'w', encoding='utf-8'), ensure_ascii=False, indent=2)
"
Step 4:关键帧提取
"$FFMPEG" -i "video.mp4" -vf "fps=1/60" -q:v 2 "frames/frame_%04d.jpg"
短视频(<15分钟)可跳过。
> 关键帧用途:存入 frames/,分析时用于"📖 借鉴学习"的"2 个绘图"——选取有信息量的帧作为配图参考,标注时间戳对应内容段落。
Step 5:保存原文转写
mkdir -p "E:/知识库/03-视频来源/{人物}/"
文件命名:transcript_{来源简称}_{YYYY-MM-DD}.txt
Step 6:分段分析(⚠️ 长视频强制)
> 核心原则:转写文本 ≤8000 字 → 一次性分析;>8000 字 → 分段分析后合并。
6.1 判断是否需要分段
wc -m "output/transcript.txt"
# ≤8000 → 跳转到 Step 6.5 直接分析
# >8000 → 执行以下分段流程
6.2 自动分段
按自然段落(空行)切分,每段约 3000-4000 字,保持段落完整性:
with open('output/transcript.txt', 'r', encoding='utf-8') as f:
text = f.read()
paras = text.split('\n\n')
chunks = []
current = ''
for p in paras:
if len(current) + len(p) > 4000 and current:
chunks.append(current)
current = p
else:
current += '\n\n' + p if current else p
if current:
chunks.append(current)
print(f'Total segments: {len(chunks)}')
for i, c in enumerate(chunks):
print(f'Chunk {i+1}: {len(c)} chars')
6.3 逐段提取要点
每段独立提取:
- 时间段(参考 SRT 时间戳)
- 核心主题(1 句话)
- 关键人物/机构/事件
- 重要数据/引述
- 值得标记的观点(用作③亮点思考素材)
6.4 跨段合并与去重
所有段分析完毕后:
1. 合并同类主题(不同段讨论同一话题 → 归并)
2. 去重(同一事件被多段提及 → 保留首次完整记录)
3. 整理时间线(按时间顺序排列事件)
6.5 五模块分析
> 基于合并后的要点摘要,按 zotero-note-template 五模块模板生成最终分析(见第五章)。
视频 ≥60 分钟的,②基本框架里必须包含"分段内容概要"表格:
| 时间段 | 时长 | 主题 |
|---|---|---|
| 00:00-15:00 | 15min | xxx |
| 15:00-30:00 | 15min | xxx |
| ... | ... | ... |
四、Phase 2B:文本管线
Step 1:WebFetch → 抓取全文
Prompt 要求提取:标题、日期、公众号名称、全文(完整不省略)、涉及公司/人物/技术/话题。
Step 2:保存原文(按来源分类)
- 公众号文章 →
E:/知识库/04-公众号来源/YYYY-MM/,命名原文_{公众号名}_{YYYY-MM-DD}.txt - 其他网页/本地文稿 →
E:/知识库/05-其它来源/,命名原文_{来源}_{YYYY-MM-DD}.txt
mkdir -p "E:/知识库/04-公众号来源/YYYY-MM/"
mkdir -p "E:/知识库/05-其它来源/"
Step 3:结构化分析
> 使用统一的 zotero-note-template 五模块模板(见第五章)。
Step 4:自检
执行顶部"⛔ 强制自检"三条 Bash 命令,确认通过。
五、统一输出模板(zotero-note-template)
> 严格遵循 MEMORY.md 中定义的「文献评述标准(对齐 Obsidian zotero-note-template)」,不做任何改动。
模板正文
📝 摘要 — 论文基本信息(标题、作者、年份、期刊、期刊等级)+ 核心论点一句话总结
📋 基本框架
- 背景:研究的现实/学术背景,要解决什么痛点
- 目的与问题:核心研究问题,作者想回答什么
- 方法与数据:研究方法 + 数据来源,二者紧密关联
- 结论:文章的最终定论,注意区分"结果"和"结论"
💡 亮点思考
- 优点:方法论创新、论证力度、实践厚度等
- 不足:需尖锐判断,不回避直接评价(方法缺陷、论证漏洞、样本局限等),忌温和客套
- 存疑 / 待验证:推理链中不确定的环节、缺乏证据的主张、需后续验证的假设
- 亮点:可迁移到自身研究的具体技巧(论证策略、数据用法、表述方式等)
📖 借鉴学习(125)
- 1 个思路:可能为自身研究带来的新思路(实验方法或研究思路)
- 2 个绘图:文中设计精良的图表,分析其形式和色彩搭配
- 5 个句式:可模仿的5个优秀句式
🔗 关联与脉络
- 该文献在研究网络中的位置(前承哪些?后启哪些?横向对比谁?)
- 与自身研究的实际关系(互补/冲突/填补空白/可忽略),避免模板化三段式
> 📎 原文链接:{原始URL}
质量控制
| 要求项 | 标准 |
|---|---|
| 字节数 | ≥10,000(黄线 8,000) |
| 模块数 | = 5(zotero-note-template 五模块,缺一不可) |
| 主观判断密度 | ≥2-3 处(存疑/有待验证/不排除/笔者认为等) |
| 不足评价 | 不做温和客套,直接点出问题 |
| 关联与脉络 | 按实际关系差异化,禁用"互补/理论基础/对笔者研究而言"模板化套话 |
| Tags | 七维度必覆盖 + 只用白名单 |
| 来源链接 | 末尾必须附 📎 原文链接 |
视频时长与深度对应
| 视频时长 | 处理方式 | 目标字节数 | 最低字节数 |
|---|---|---|---|
| <15分钟 | 一次性分析 | 8,000-12,000 | 8,000 |
| 15-30分钟 | 一次性分析 | 10,000-16,000 | 9,000 |
| 30-60分钟 | 视字数决定(≤8000字一次性,>8000字分段) | 14,000-22,000 | 12,000 |
| 60-90分钟 | 分段分析(2-3段) | 20,000-30,000 | 16,000 |
| 90-150分钟 | 分段分析(3-4段) | 28,000-40,000 | 22,000 |
| >150分钟 | 分段分析(4-6段),含②基本框架分段概要表 | ≥40,000 | 30,000 |
本地文件管线
| 文件类型 | 跳过步骤 | 执行步骤 | 输出路径 |
|---|---|---|---|
本地视频 .mp4 |
跳过下载 | 音频提取→转写→关键帧→分析→自检 | 03-视频来源/{人物}/ |
本地音频 .m4a |
跳过下载+音频提取 | 转写→分析→自检 | 03-视频来源/{人物}/ |
本地文本 .txt/.md |
跳过抓取 | 直接分析→自检 | 05-其它来源/ |
分析方法论(内容 → 模板的映射规则)
原始内容(转写文本 / 公众号文章)到五模块模板的映射,遵循以下推导链:
📝 摘要 → 从内容中提取:谁说的/写的、什么时候、通过什么渠道、核心主张是什么。一句话就是"这个内容在说什么"。
📋 基本框架 → 拆解内容的论证结构:
- 背景:内容针对的行业/学术问题是什么?为什么现在要讨论这个?
- 目的与问题:内容试图回答或解决什么?
- 方法与数据:内容用什么证据支撑?(引用什么数据、案例、实验?)
- 结论:最终落点在哪?注意把"说的内容"(发现)和"想传达的意思"(结论)分开
💡 亮点思考 → 跳出内容本身做判断:
- 优点:论证链是否完整?证据是否充分?洞察是否独到?
- 不足:哪里说不通?什么被回避了?样本/论据有什么问题?不客套
- 存疑/待验证:哪些声称需要外部验证?用 WebSearch 标注 ✅/⚠️/🔴
- 亮点:有什么技巧/框架可以直接借鉴?
📖 借鉴学习(125) → 提炼可复用的东西:
- 1 个思路:内容中最底层的分析逻辑或认知框架
- 2 个绘图:必须写入真实可渲染的 Mermaid 代码块(Obsidian 原生支持)。每张图 = 文字说明 + mermaid 代码块。用 graph LR/TD、flowchart、erDiagram 等表达核心逻辑关系。视频分析可辅以关键帧截图
- 5 个句式:摘出 5 个值得模仿的表达方式(论证转折、判断措辞、数据呈现等)
> Mermaid 图规范:代码块语言标 mermaid;节点用中文;核心概念 5-8 个节点以内,超过则分层;关系用箭头标注因果/流程,用 --- 表示并列关联。图要能脱离文字独立看懂。
🔗 关联与脉络 → 把内容放回网络中:
- 此前有什么相关讨论?此后会引发什么?横向有什么对立观点?
- 和数据库里已有的其他内容有什么关系?具体到哪篇、什么关系
> ⚠️ 关键区分:模板是 Zotero 文献分析格式,但输入内容是视频/公众号。不要生搬"论文""文献""期刊"等词,而是用模板的分析结构来处理任何内容类型。
六、输出路径
| 产物 | 路径 | 命名规则 |
|---|---|---|
| 视频分析报告 | E:/知识库/03-视频来源/{人物}/ |
YYYY-MM {关键事件/主题}.md |
| 视频原文转写 | E:/知识库/03-视频来源/{人物}/ |
transcript_{来源简称}_{YYYY-MM-DD}.txt |
| 公众号分析报告 | E:/知识库/04-公众号来源/YYYY-MM/ |
YYYY-MM {来源} - {关键标签}.md |
| 公众号原文 | E:/知识库/04-公众号来源/YYYY-MM/ |
原文_{公众号名}_{YYYY-MM-DD}.txt |
| 其它文件/文稿 | E:/知识库/05-其它来源/ |
YYYY-MM {来源} - {关键标签}.md |
| 中间产物 | 项目 output_{简称}/ |
可清理 |
| 学习报告 | state/latest_learning_report.json |
自动生成 |
| 学习状态 | state/learning_state.json |
持久化 |
| 用户反馈 | state/pending_feedback.json |
累积存储 |
七、Phase 3:自学习机制
7.1 触发条件
| 条件 | 阈值 | 检查方式 |
|---|---|---|
| 增量触发 | ≥20 篇新增 | 对比 state/learning_state.json |
| 时间触发 | ≥7 天 | 对比上次扫描时间 |
| 反馈触发 | ≥3 条 | 读取 state/pending_feedback.json |
| 手动触发 | 即时 | 用户说"框架学习""跑自学习" |
python scripts/learn_from_db.py --check-trigger --db-path "E:/知识库"
7.2 数据库扫描
python scripts/learn_from_db.py --scan --db-path "E:/知识库"
输出 → state/latest_learning_report.json
扫描维度:
- 标签层面:频率统计、高频缺失概念、长期未使用标签、维度覆盖缺口
- 模块层面:各模块缺失率,>15% → 建议强化
- 质量层面:字节数趋势(近10篇 vs 整体),下降且低于黄线 → 建议提高标准
- 词库层面:扫描所有 transcript.txt,检查词库中已知识别错误是否残留。有残留 → 建议增加词库条目或排查后处理流程
- 内容完整性:检查每篇分析的模块子项是否齐全(如 💡亮点思考 是否含 优点+不足+存疑+亮点 四子项)
- 引用分析:汇总 🔗关联与脉络 中出现的文献引用,排序高频文献
- 重复检测:标题模糊匹配,发现疑似重复内容
7.3 用户反馈
内联反馈:直接说改进需求。
结构化反馈:
@framework: 建议新增标签 研究/技术/生成式设计
@framework: 📖借鉴学习中5个句式建议提升到8个
@framework: 💡亮点思考增加"方法局限"子维度
反馈 → 追加到 state/pending_feedback.json → 下次扫描纳入分析。
7.4 生成学习报告 + 用户确认
扫描完成 → 呈现逐条建议(标注 P0/P1/P2)→ P0 必须逐条确认,P1/P2 可批量 @framework: approve all
7.5 知识库 git 自动备份(安全基线)
知识库已纳入 git 版本控制(E:/知识库/.git)。每次自学习扫描结束后、以及每完成 5 篇分析后,执行:
cd "E:/知识库" && git add -A && git commit -m "backup: 知识库自动备份 $(date +%Y-%m-%d)" 2>&1 | tail -1
规则:
- .obsidian/ 已排除(插件缓存可重装)
- 提交失败(如无可提交内容)忽略即可,无需处理
- 禁止 git push 到任何远程仓库(知识库含考研笔记等隐私,仅本地备份)
- 回滚方法:git log --oneline 找到历史提交 → git checkout <commit> -- <文件路径> 恢复单个文件
7.6 框架更新执行协议
> ⛔ 强制收尾序列(不可跳过,任何一步缺失视同自检未通过,禁止进入下一轮自学习):
Step 1: 更新 references/tags_taxonomy.txt(本 skill)
新增标签追加到对应维度区块,废弃标签注释保留
Step 2: 更新 references/terminology_dict.txt
新增 错误→正确 词条,版本号递增
Step 3: 同步知识库规则
→ E:/知识库/01-学习日志,规则/tags_taxonomy.txt
→ E:/知识库/01-学习日志,规则/数据库标签规则vX.X.md
→ E:/知识库/01-学习日志,规则/转写术语纠错词典vX.X.txt
Step 4: 更新 state/learning_state.json
last_scan/entries_at_scan/cycle_count/scan_history/skill_sync_log
Step 5: ⛔ 记录自学习日志(7 维度格式)——本步不可省略
→ E:/知识库/01-学习日志,规则/Cycle-XX_描述.md
日志模板(含维度 8 双链聚类):
# Cycle-XX:描述
- 日期 / 版本 / 扫描范围 / 白名单
## 一、标签层面(新增/废弃/覆盖)
## 二、模块层面(覆盖率)
## 三、质量层面(字节趋势)
## 四、词库层面(转录残留)
## 五、内容完整性(子项缺失)
## 六、引用分析(高频引用)
## 七、重复检测(疑似重复)
## 八、双链聚类(候选/写入)
## 总结(需变更/健康)
Step 6: ⛔ git 提交知识库(安全基线)
cd "E:/知识库" && git add -A && git commit -m "feat: 框架学习 Cycle-XX 应用结果"
Step 7: 验证一致性
references/tags_taxonomy.txt ✓
references/terminology_dict.txt ✓
state/learning_state.json ✓
Cycle-XX 日志 ✓
git 提交 ✓
> 收尾顺序铁律:应用变更 → 写 Cycle 日志(Step 5) → git 提交(Step 6),三步连续完成,中间不插入其他任务。日志缺失时禁止把 state 更新当作完成标志——state 是机器记录,Cycle 日志是给人看的报告,两者职责不同,必须分别完成。
7.6 关键规则
- 用户确认门禁:所有框架变更必须先经用户确认,不可自动执行
- 版本号管理:每次变更必须更新
framework_version - 存量不回溯:框架变更仅影响新报告
- 状态持久化:所有记录写入 JSON
- 五篇提醒:处理 ≥5 篇未触发自学习时,提醒考虑手动触发
八、快速参考:典型对话
用户: "帮我分析 https://b23.tv/xxx 和 https://mp.weixin.qq.com/s/yyy"
research-hub 执行:
1. [Phase 1] 检测:
- b23.tv/xxx → B站视频 → 视频管线
- mp.weixin.qq.com/s/yyy → 公众号 → 文本管线
2. [Phase 2B] 先文本(轻量快速):
WebFetch→保存原文→五模块分析→自检→通过 ✅
3. [Phase 2A] 再视频:
下载→音频→转写→关键帧→保存转写→五模块分析→交叉验证→自检→通过 ✅
4. [Phase 3] 检查自学习:
本次 +2 篇,DB 累计 193 篇 → 距触发还需 18 篇
"处理完成。累计 193 篇,距学习触发还需 18 篇。"
其他文件处理
用户: "分析这份文件 D:/reports/行业深度2026.txt"
research-hub:
1. [Phase 1] 检测 → 本地文本文件 → 文本管线
2. [Phase 2B] 读取文件→五模块分析→自检→存入 05-其它来源/
用户: "跑一下自学习"
→ 手动触发 Phase 3
→ 扫描 DB → 生成报告 → 逐条确认 → 执行 6 步更新协议
九、关键约束
- ⛔ 强制自检:写完每篇 .md 后即刻 Bash 验证(字节数 + 模块数 + 七维度),不通过不下一篇。
- ⛔ 标签合规:只用白名单、八维度必覆盖、禁止自编。
- ⛔ 内容深度:每篇按 zotero-note-template 五模块完整模板,字节数 ≥10,000。📋基本框架四要素全覆、💡亮点思考四要素全覆、📖借鉴学习(1-2-5)结构完整。禁止及格线心态。
- ⛔ 五篇重置:每连续处理 5 篇后重读质量标准。
- ⛔ 框架变更需确认:自学习生成的更新必须经用户确认。
- ⛔ 路由前先检测:不假设输入类型。
- ⛔ 禁止擅自修改:任何文件/标签/目录结构改动前告知用户。
- ⛔ 先查再断:不能默认"还在跑"。状态查询先用
ls/wc确认事实再做判断。 - ⛔ 内容基于来源:分析中所有事实引用、人名、案例、数据、政策文件必须来自原始内容,不得凭空添加。主观判断标注"笔者认为""不排除"等,推测与事实明确区分。禁止为了丰富分析而编造引用。
- 转写质量:faster-whisper(GPU 自动检测,无 GPU 用 CPU INT8 属正常),语言自动检测,术语后处理必做。
十、技术栈
- B站/YouTube 下载:yt-dlp(B站需禁用代理)
- 音频提取:imageio_ffmpeg 自动路径检测
- 语音转写:faster-whisper(GPU 自动检测 / CPU INT8)+ 语言自动检测 + 术语词典
⛔ pip 安装铁律(2026-08-09 实测)
国内网络环境下,pip 安装任何包必须使用清华镜像,禁止直连官方源(pytorch.org 等官方源下载 torch 实测 22 分钟无进展,清华镜像 1 分 24 秒完成):
pip install <包名> -i https://pypi.tuna.tsinghua.edu.cn/simple
统一转写环境:faster-whisper + torch(CPU)已安装在 managed Python(C:/Users/79072/.workbuddy/binaries/python/versions/3.13.12/python.exe)。转写一律用此环境,不再依赖系统 Python。若重装环境,用同一镜像命令恢复。
- 关键帧:imageio_ffmpeg fps 滤镜
- 文本抓取:WebFetch
- 路由检测:scripts/detect_source.py
- 数据库学习:scripts/learn_from_db.py
- 进度追踪:scripts/track_progress.py
- 标签白名单:references/tags_taxonomy.txt
- 术语词典:references/terminology_dict.txt