Phase 0-2: Schema cleanup, typed relations, event-driven automation
- Phase 0: AGENTS.md cleanup (dedup quotes, renumber sections, merge qmd) - Phase 1: typed relations (manage-relations.py, graph-search.py, check-staleness.py, detect-conflicts.py) - Phase 2: frontmatter validator, weekly lint, knowledge promotion, git hooks - Fix .gitignore to track tools/ and .githooks/ - Fix git remote URL (remove plaintext token) - New wiki pages: 504 pages, 34 raw sources
This commit is contained in:
@@ -0,0 +1,192 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
import sys
|
||||
import io
|
||||
import re
|
||||
import datetime
|
||||
from pathlib import Path
|
||||
from typing import Dict, List, Set, Tuple
|
||||
from collections import defaultdict
|
||||
|
||||
if sys.platform == "win32":
|
||||
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8")
|
||||
sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding="utf-8")
|
||||
|
||||
|
||||
class WikilinkManager:
|
||||
def __init__(self, project_root: Path):
|
||||
self.project_root = project_root
|
||||
self.knowledge_cards_dir = project_root / "知识卡片"
|
||||
self.institution_dir = project_root / "机构档案"
|
||||
self.weekly_reports_dir = project_root / "每周报告"
|
||||
self.deep_reports_dir = project_root / "深度研究报告"
|
||||
self.wikilinks: Dict[str, Set[str]] = defaultdict(set)
|
||||
|
||||
def extract_title_from_file(self, file_path: Path) -> str:
|
||||
try:
|
||||
content = file_path.read_text(encoding="utf-8")
|
||||
fm_match = re.match(r"^---\n(.*?)\n---", content, re.DOTALL)
|
||||
if fm_match:
|
||||
for line in fm_match.group(1).split("\n"):
|
||||
if line.startswith("title:"):
|
||||
return line.replace("title:", "").strip().strip('"')
|
||||
first_heading = re.search(r"^#\s+(.+)$", content, re.MULTILINE)
|
||||
if first_heading:
|
||||
return first_heading.group(1).strip()
|
||||
except:
|
||||
pass
|
||||
return file_path.stem
|
||||
|
||||
def build_relationship_map(self) -> Dict[str, List[str]]:
|
||||
relationships = {
|
||||
"LLM教育应用": ["智能辅导系统", "自适应学习系统", "个性化学习系统"],
|
||||
"智能辅导系统": ["自适应学习系统", "CMU LearnLab", "Khanmigo"],
|
||||
"自适应学习系统": ["智能辅导系统", "个性化学习系统", "自适应学习环境"],
|
||||
"个性化学习系统": ["自适应学习系统", "自适应学习环境"],
|
||||
"智能评测技术": ["教育大数据分析", "教育机器人应用"],
|
||||
"教育大数据分析": ["智能评测技术", "教育机器人应用"],
|
||||
"教育机器人应用": ["智能评测技术", "教育大数据分析"],
|
||||
"自适应学习环境": ["自适应学习系统", "个性化学习系统"],
|
||||
"RCT研究与Cohen's d指标": ["哈佛CS50课程模式", "哈佛教务长框架"],
|
||||
"哈佛CS50课程模式": ["MIT RAISE框架", "斯坦福AI Accelerator", "牛津AIEOU"],
|
||||
"哈佛教务长框架": ["斯坦福AI Accelerator", "牛津AIEOU", "CMU LearnLab"],
|
||||
"MIT RAISE框架": ["斯坦福AI Accelerator", "Khanmigo"],
|
||||
"斯坦福AI Accelerator": ["牛津AIEOU", "CMU LearnLab", "Khanmigo"],
|
||||
"牛津AIEOU": ["CMU LearnLab", "以人为本AI教育观"],
|
||||
"CMU LearnLab": ["Khanmigo", "智能辅导系统"],
|
||||
"Khanmigo": ["斯坦福AI Accelerator", "智能辅导系统"],
|
||||
"以人为本AI教育观": ["高等教、AI全球图景"],
|
||||
"高等教育AI全球图景": ["以人为本AI教育观", "哈佛CS50课程模式"],
|
||||
}
|
||||
return relationships
|
||||
|
||||
def add_wikilinks_to_file(
|
||||
self, file_path: Path, related_concepts: List[str]
|
||||
) -> bool:
|
||||
try:
|
||||
content = file_path.read_text(encoding="utf-8")
|
||||
|
||||
if "## 相关概念" in content or "## 相关链接" in content:
|
||||
print(f" ⏭️ Skipping (already has related section): {file_path.name}")
|
||||
return False
|
||||
|
||||
section = f"""
|
||||
|
||||
---
|
||||
|
||||
## 相关概念
|
||||
|
||||
- [[{"|".join(related_concepts)}]]
|
||||
|
||||
"""
|
||||
|
||||
if content.rstrip().endswith("---"):
|
||||
content = content.rstrip() + section
|
||||
else:
|
||||
content = content.rstrip() + section
|
||||
|
||||
file_path.write_text(content, encoding="utf-8")
|
||||
print(f" ✅ Added related concepts to: {file_path.name}")
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
print(f" ❌ Error adding wikilinks to {file_path.name}: {e}")
|
||||
return False
|
||||
|
||||
def process_knowledge_cards(self):
|
||||
relationships = self.build_relationship_map()
|
||||
|
||||
if not self.knowledge_cards_dir.exists():
|
||||
print(f"⚠️ Knowledge cards directory not found")
|
||||
return
|
||||
|
||||
card_files = list(self.knowledge_cards_dir.glob("*.md"))
|
||||
print(f"\nProcessing {len(card_files)} knowledge cards...")
|
||||
|
||||
updated_count = 0
|
||||
for card_file in card_files:
|
||||
card_name = card_file.stem.replace("-知识卡片", "")
|
||||
|
||||
related = relationships.get(card_name, [])
|
||||
if related:
|
||||
result = self.add_wikilinks_to_file(card_file, related)
|
||||
if result:
|
||||
updated_count += 1
|
||||
|
||||
return updated_count
|
||||
|
||||
def generate_cross_reference_report(self) -> str:
|
||||
relationships = self.build_relationship_map()
|
||||
|
||||
report = f"""# 跨文档引用增强报告
|
||||
|
||||
## 基本信息
|
||||
|
||||
- **生成时间**: {datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")}
|
||||
- **涉及知识卡片**: {len(relationships)} 个
|
||||
|
||||
## 关系映射
|
||||
|
||||
| 概念 | 相关概念 |
|
||||
|------|----------|
|
||||
"""
|
||||
|
||||
for concept, related in sorted(relationships.items()):
|
||||
report += f"| {concept} | {', '.join(related)} |\n"
|
||||
|
||||
report += f"""
|
||||
|
||||
## 更新统计
|
||||
|
||||
- **已更新文件**: 在知识卡片末尾添加了"相关概念"章节
|
||||
- **链接格式**: 使用Obsidian wikilink格式 `[[概念名]]`
|
||||
- **关系类型**: 学科关联、技术关联、应用关联
|
||||
|
||||
## 下一步建议
|
||||
|
||||
1. 在机构档案中添加相关知识卡片链接
|
||||
2. 在周报和深度报告中添加更多内部引用
|
||||
3. 定期检查和更新跨文档引用
|
||||
4. 考虑建立双向链接(反向引用)
|
||||
|
||||
---
|
||||
|
||||
*报告生成时间: {datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")}*
|
||||
"""
|
||||
|
||||
return report
|
||||
|
||||
|
||||
def main():
|
||||
print("=" * 60)
|
||||
print("Cross-Document References Enhancement Tool")
|
||||
print("=" * 60)
|
||||
print(f"Execution time: {datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
|
||||
print()
|
||||
|
||||
project_dir = Path(__file__).parent.parent
|
||||
manager = WikilinkManager(project_dir)
|
||||
|
||||
updated = manager.process_knowledge_cards()
|
||||
|
||||
report = manager.generate_cross_reference_report()
|
||||
report_path = (
|
||||
project_dir
|
||||
/ "outputs"
|
||||
/ f"cross_reference_enhancement_{datetime.date.today()}.md"
|
||||
)
|
||||
report_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
with open(report_path, "w", encoding="utf-8") as f:
|
||||
f.write(report)
|
||||
|
||||
print()
|
||||
print("=" * 60)
|
||||
print("Enhancement Complete")
|
||||
print("=" * 60)
|
||||
print(f"Files updated: {updated}")
|
||||
print(f"Report saved to: {report_path.name}")
|
||||
print("=" * 60)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user