# Karpathy风格 Wiki 自动编译器设计文档 > 基于LLM的个人知识库自动构建系统 ## 一、核心架构 ``` ┌─────────────────────────────────────────────────────────────────┐ │ 腾讯云 2核2G (编译服务器) │ │ │ │ /data/knowledge-base/ │ │ ├── 00-inbox/ ← 原始资料入口(手动/Web Clipper放入) │ │ ├── 01-raw/ ← 已整理的原始资料(PDF/网页/图片) │ │ ├── 02-compiler/ ← 编译器工作目录 │ │ │ ├── scripts/ ← 编译脚本 │ │ │ ├── queue/ ← 待处理队列 │ │ │ └── logs/ ← 处理日志 │ │ ├── 03-wiki/ ← 生成的Wiki(Obsidian主目录) │ │ │ ├── Concepts/ ← 概念文章(LLM生成) │ │ │ ├── Summaries/ ← 资料摘要 │ │ │ ├── MOCs/ ← 内容地图 │ │ │ └── Index.md ← 主索引 │ │ ├── 04-outputs/ ← 查询输出(问答/可视化) │ │ └── 05-archive/ ← 归档 │ │ │ │ 编译服务: │ │ ├── File Watcher (inotify) ← 监控inbox新文件 │ │ ├── Compiler Pipeline ← 调用LLM处理 │ │ └── WebDAV Server ← 供Obsidian同步 │ └─────────────────────────────────────────────────────────────────┘ ↑ WebDAV / HTTPS ↑ ┌─────────────────────┼─────────────────────┐ │ │ │ MacBook 手机/iPad (其他设备) (Obsidian IDE) (Obsidian App) (也可本地编译) ``` ## 二、编译流程设计 ### 2.1 阶段一:数据摄取(Ingest) **输入**:任意格式的原始资料 - 网页文章(通过Obsidian Web Clipper) - PDF论文 - 图片/截图 - GitHub仓库 - 数据集说明 **处理**: ```bash # 1. 文件放入 00-inbox/ # 2. File Watcher检测到新文件 # 3. 预处理: # - 网页 → Markdown(readability-lxml) # - PDF → Markdown(pymupdf4llm) # - 图片 → OCR提取文字(可选) # 4. 移动到 01-raw/,记录元数据 ``` **元数据记录**(JSON sidecar): ```json { "source": "https://example.com/article", "title": "原始标题", "author": "作者", "date_ingested": "2025-04-15", "file_type": "web_article", "word_count": 3500, "hash": "sha256:xxx", "status": "pending_compilation" } ``` ### 2.2 阶段二:编译(Compile) **核心编译管道**(每次处理一个文档): ```python # compiler.py 伪代码 def compile_document(raw_file): # 1. 读取原始内容 content = read_raw(raw_file) metadata = read_sidecar(raw_file) # 2. LLM生成摘要(500字以内) summary = llm_call( model="claude-3-5-sonnet", prompt=f""" 请为以下文章生成结构化摘要: - 一句话核心观点 - 3-5个关键要点 - 重要数据/事实 - 与其他概念的潜在联系 原文:{content[:8000]} # 前8K字符 """ ) # 3. LLM提取概念 concepts = llm_call( prompt=f""" 从以下文章中提取关键概念(实体、理论、方法、工具等)。 对每个概念给出:名称、定义、重要性(1-5)、相关概念 格式:YAML列表 """ ) # 4. 生成或更新概念文章 for concept in concepts: concept_file = f"03-wiki/Concepts/{concept.name}.md" if exists(concept_file): # 更新现有概念(添加新信息) update_concept(concept_file, concept, raw_file) else: # 创建新概念文章 create_concept(concept_file, concept, raw_file) # 5. 生成资料摘要卡片 summary_file = f"03-wiki/Summaries/{raw_file.basename}.md" create_summary_card(summary_file, summary, concepts, metadata) # 6. 更新主索引 update_index() # 7. 生成反向链接 create_backlinks(raw_file, concepts) return { "status": "compiled", "summary": summary_file, "concepts": [c.name for c in concepts], "links_created": len(concepts) } ``` **概念文章模板**(LLM生成): ```markdown --- concept: "概念名称" aliases: ["别名1", "别名2"] importance: 4 created: 2025-04-15 last_updated: 2025-04-15 sources: - "[[Summaries/原始文章1]]" - "[[Summaries/原始文章2]]" related: - "[[概念A]]" - "[[概念B]]" --- # 概念名称 ## 定义 (LLM生成的简洁定义,50-100字) ## 核心要点 - 要点1 - 要点2 - 要点3 ## 在资料中的出现 (自动聚合所有提到此概念的原始资料) ### [[Summaries/原始文章1]] > 引用段落... > 引用段落... ### [[Summaries/原始文章2]] > 引用段落... ## 相关概念 - [[概念A]]:关系说明... - [[概念B]]:关系说明... ## 待探索问题 (LLM自动生成,供后续查询) - 这个概念与X有什么区别? - 在Y场景下如何应用? ``` ### 2.3 阶段三:MOC生成(Map of Content) **自动生成内容地图**: ```python def generate_mocs(): # 1. 分析所有概念的关系 concepts = load_all_concepts() graph = build_concept_graph(concepts) # 2. LLM识别主题集群 clusters = llm_call( prompt=f""" 以下是我知识库中的所有概念(共{len(concepts)}个)。 请将它们组织成5-10个主题集群(MOC),每个集群包含: - 主题名称 - 核心概念列表 - 集群间的联系 概念列表:{concepts} 关系图:{graph} """ ) # 3. 为每个集群生成MOC文件 for cluster in clusters: moc_file = f"03-wiki/MOCs/{cluster.name}.md" create_moc(moc_file, cluster) # 4. 更新主索引 update_master_index(clusters) ``` **MOC文件模板**: ```markdown --- moc: true title: "人工智能研究" description: "关于AI核心概念、方法论的集合" concepts_count: 42 last_updated: 2025-04-15 --- # 🗺️ 人工智能研究 ## 核心概念 (Dataview查询自动生成) ```dataview LIST FROM "Concepts" WHERE contains(mocs, "人工智能研究") SORT importance DESC ``` ## 重要资料 ```dataview LIST FROM "Summaries" WHERE contains(topics, "AI") SORT file.mtime DESC LIMIT 10 ``` ## 最新探索 (手动或自动记录的研究问题) - [ ] 大模型微调的最佳实践? - [ ] RAG vs 长上下文,何时用哪个? ## 关联MOC - [[机器学习基础]] - [[自然语言处理]] ``` ### 2.4 阶段四:问答与输出(Q&A) **基于Wiki的问答机制**: ```python def query_wiki(question): # 1. 确定相关概念 relevant_concepts = llm_call( prompt=f""" 用户问题:{question} 请从以下概念列表中,找出最相关的5-10个概念: {all_concepts} 返回概念名称列表。 """ ) # 2. 读取相关概念文章 context = "" for concept in relevant_concepts: context += read_concept_file(concept) # 3. 可选:读取原始资料(如果需要更多细节) if need_more_detail(question): raw_sources = find_raw_sources(relevant_concepts) context += extract_relevant_parts(raw_sources, question) # 4. LLM生成回答 answer = llm_call( prompt=f""" 基于以下Wiki内容,回答用户问题。 如果信息不足,请明确说明。 上下文:{context[:12000]} # 限制长度 问题:{question} 要求: - 使用中文回答 - 引用来源概念(如[[概念名称]]) - 如果涉及多个方面,分点说明 """ ) # 5. (可选)生成输出文档 if user_wants_output: output_file = f"04-outputs/QnA-{timestamp}.md" create_qna_doc(output_file, question, answer, relevant_concepts) return answer ``` **可视化输出**(可选): ```python def generate_visualization(query_type): if query_type == "concept_graph": # 生成概念关系图(Mermaid或D3) pass elif query_type == "timeline": # 生成时间线 pass elif query_type == "slides": # 生成Marp幻灯片 pass ``` ### 2.5 阶段五:健康检查与增强(Linting) **定期检查任务**(每日/每周): ```python def health_check(): # 1. 查找孤立概念(无链接的概念) orphans = find_orphan_concepts() # 2. 查找矛盾信息 contradictions = llm_call( prompt="扫描所有概念文章,标记矛盾或过时的信息" ) # 3. 建议新文章 gaps = llm_call( prompt="基于现有概念,建议缺失的链接文章或MOC" ) # 4. 生成健康报告 report = generate_report(orphans, contradictions, gaps) save_to("04-outputs/health-reports/weekly.md") ``` ## 三、技术实现细节 ### 3.1 文件监控与触发 **使用inotify(Linux)**: ```python # file_watcher.py import inotify.adapters def watch_inbox(): i = inotify.adapters.Inotify() i.add_watch('/data/knowledge-base/00-inbox') for event in i.event_gen(yield_nones=False): (_, type_names, path, filename) = event if 'IN_CLOSE_WRITE' in type_names: # 新文件写入完成,触发编译 queue_for_compilation(os.path.join(path, filename)) ``` **备选:定时扫描**: ```bash # cron任务,每分钟检查 * * * * * /usr/bin/python3 /data/knowledge-base/compiler/scan_inbox.py ``` ### 3.2 队列管理 **使用Redis或简单文件队列**: ```python # queue.py - 简化版文件队列 import json import os from datetime import datetime QUEUE_DIR = "/data/knowledge-base/02-compiler/queue" def enqueue(file_path, priority=5): task = { "id": generate_id(), "file": file_path, "priority": priority, # 1-10, 10最优先 "status": "pending", "created": datetime.now().isoformat(), "attempts": 0 } queue_file = os.path.join(QUEUE_DIR, f"{task['id']}.json") with open(queue_file, 'w') as f: json.dump(task, f) def dequeue(): """按优先级取出任务""" tasks = [] for f in os.listdir(QUEUE_DIR): if f.endswith('.json'): with open(os.path.join(QUEUE_DIR, f)) as fp: task = json.load(fp) if task['status'] == 'pending': tasks.append(task) # 按优先级排序 tasks.sort(key=lambda x: x['priority'], reverse=True) return tasks[0] if tasks else None ``` ### 3.3 LLM调用封装 **统一接口,支持多后端**: ```python # llm_client.py import os from typing import Literal Backend = Literal["claude", "openai", "kimi", "local"] class LLMClient: def __init__(self, default_backend: Backend = "claude"): self.default = default_backend self.api_keys = { "claude": os.getenv("ANTHROPIC_API_KEY"), "openai": os.getenv("OPENAI_API_KEY"), "kimi": os.getenv("MOONSHOT_API_KEY"), "local": "http://localhost:11434" # Ollama } def call(self, prompt: str, backend: Backend = None, **kwargs): backend = backend or self.default if backend == "claude": return self._call_claude(prompt, **kwargs) elif backend == "openai": return self._call_openai(prompt, **kwargs) elif backend == "kimi": return self._call_kimi(prompt, **kwargs) elif backend == "local": return self._call_ollama(prompt, **kwargs) def _call_claude(self, prompt, model="claude-3-5-sonnet-20241022", max_tokens=4000): import anthropic client = anthropic.Anthropic(api_key=self.api_keys["claude"]) message = client.messages.create( model=model, max_tokens=max_tokens, messages=[{"role": "user", "content": prompt}] ) return message.content[0].text # ... 其他后端的实现 ``` ### 3.4 WebDAV配置 **使用WsgiDAV**: ```bash # 安装 pip install wsgidav cheroot # 配置 /etc/wsgidav.yaml host: 0.0.0.0 port: 5232 root: /data/knowledge-base/03-wiki auth: type: htpasswd htpasswd_filename: /etc/wsgidav/users.htpasswd # SSL(通过Nginx反向代理) ``` **Nginx反向代理配置**: ```nginx server { listen 443 ssl http2; server_name knowledge.yourdomain.com; ssl_certificate /path/to/cert.pem; ssl_certificate_key /path/to/key.pem; # WebDAV location / { proxy_pass http://localhost:5232; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; # WebDAV方法 dav_methods PUT DELETE MKCOL COPY MOVE; dav_ext_methods PROPFIND OPTIONS; } # API网关(编译器API) location /api/ { proxy_pass http://localhost:8000; proxy_set_header Authorization $http_authorization; } } ``` ## 四、Obsidian配置 ### 4.1 必需插件 1. **Remotely Save** - WebDAV同步 2. **Dataview** - 查询和索引 3. **Templater** - 模板自动化 4. **QuickAdd** - 快速捕获 5. **Obsidian Web Clipper**(浏览器扩展)- 剪藏网页 ### 4.2 快捷键配置 ```json { "快速捕获到inbox": "Ctrl+Shift+I", "触发编译当前文件": "Ctrl+Shift+C", "打开概念图谱": "Ctrl+Shift+G", "查询Wiki": "Ctrl+Shift+Q" } ``` ### 4.3 模板示例 **新资料模板**(放入00-inbox时自动添加): ```markdown --- ingest_date: {{date}} source: {{source_url}} status: pending priority: 5 tags: [raw] --- # {{title}} [原始链接]({{source_url}}) ## 内容 {{content}} ## 待处理 - [ ] 编译成摘要 - [ ] 提取概念 - [ ] 链接到相关MOC ``` ## 五、部署清单 ### 5.1 腾讯云初始化 ```bash # 1. 系统更新 sudo apt update && sudo apt upgrade -y # 2. 安装依赖 sudo apt install -y python3 python3-pip nodejs npm redis-server nginx # 3. 安装Python包 pip3 install anthropic openai pymupdf4llm readability-lxml markdown pyyaml watchdog # 4. 创建目录结构 sudo mkdir -p /data/knowledge-base/{00-inbox,01-raw,02-compiler,03-wiki,04-outputs,05-archive} sudo chown -R $USER:$USER /data/knowledge-base # 5. 配置环境变量 export ANTHROPIC_API_KEY="your-key" export OPENAI_API_KEY="your-key" export MOONSHOT_API_KEY="your-key" # 6. 启动服务 # - WebDAV # - File Watcher # - Compiler Worker ``` ### 5.2 服务脚本 **systemd服务:编译器工作器** ```ini # /etc/systemd/system/wiki-compiler.service [Unit] Description=Wiki Compiler Worker After=network.target [Service] Type=simple User=ubuntu WorkingDirectory=/data/knowledge-base ExecStart=/usr/bin/python3 /data/knowledge-base/compiler/worker.py Restart=always RestartSec=10 Environment="ANTHROPIC_API_KEY=xxx" Environment="OPENAI_API_KEY=xxx" [Install] WantedBy=multi-user.target ``` ## 六、使用工作流 ### 日常流程 ``` 1. 发现资料 ↓ 2. Web Clipper剪藏 → 自动放入00-inbox/ ↓ 3. File Watcher检测 → 触发编译队列 ↓ 4. Compiler Worker处理: - 预处理 → 01-raw/ - LLM生成摘要 → 03-wiki/Summaries/ - LLM提取概念 → 03-wiki/Concepts/ - 更新MOC → 03-wiki/MOCs/ - 建立反向链接 ↓ 5. Obsidian自动同步(通过WebDAV) ↓ 6. 在Obsidian中查看生成的Wiki ``` ### 查询流程 ``` 1. 在Obsidian中打开查询面板(或命令行) ↓ 2. 输入问题 ↓ 3. 系统: - 识别相关概念 - 读取Concepts/和Summaries/ - 组装上下文 - 调用LLM生成回答 ↓ 4. 输出: - 直接回答(聊天形式) - 或生成文档 → 04-outputs/ - 或生成可视化(图表/幻灯片) ``` ## 七、扩展思路 ### 7.1 未来增强 1. **语义搜索**:用向量数据库存储embedding,支持模糊查询 2. **多模态**:处理图片、音频、视频内容 3. **协作**:多人共享Wiki,权限管理 4. **版本控制**:Git集成,追踪概念演变 5. **AI Agent**:让LLM主动提出问题、建议研究方向 ### 7.2 与OpenClaw集成 可以设计一个OpenClaw Skill: - `/wiki ingest ` - 让Val帮你剪藏和编译 - `/wiki query ` - 查询你的知识库 - `/wiki stats` - 查看知识库统计 Val可以直接调用腾讯云的编译API,帮你管理个人知识库。 --- > **核心原则**:LLM维护Wiki,人负责提出问题和判断价值。 这是一个活的系统,随着使用它会越来越懂你的知识结构和兴趣方向。