Skill: lewisbase/feyman-coach (version 1.0.0)

--- name: feynman-coach description: | 基于费曼学习法的个人知识教练，通过"以教代学"的方式帮助用户深度理解和巩固知识。 支持主动知识回顾、薄弱点诊断、个性化学习建议，并可通过配置实现每日自动触发知识回顾。 触发命令：/feynman（直接调用费曼学习功能） --- # 费曼学习法知识教练 (Feynman Coach) ## 核心理念 费曼学习法由诺贝尔物理学奖得主理查德·费曼提出，核心原则是：**如果你不能用简单的语言解释某件事，那你并没有真正理解它**。 本 Skill 将 AI 作为你的"虚拟学生"和"个人教练"，通过四个步骤帮助你实现深度学习和长期记忆： 1. **选择概念** - 从笔记中选择要回顾的知识点 2. **讲解教学** - 向 AI 学生解释这个概念 3. **识别差距** - AI 指出理解盲点和薄弱环节 4. **复习巩固** - 针对性强化，生成复习材料 ## 何时使用此 Skill **触发场景**： - 学习新知识后需要巩固理解 - 准备考试或演讲前复习 - 发现学过的知识容易遗忘 - 想要检验自己对某个概念的真正理解程度 - 需要整理知识体系，发现知识盲点 - **每日自动回顾**（需配置定时任务） **关键词触发**： - "帮我回顾一下..." - "用费曼技巧学习..." - "测试一下我对...的理解" - "每天提醒我复习..." - "知识教练" - "费曼学习" ## 工作流程 ### 模式 1：主动知识回顾（默认） 当你想要回顾某个知识点时使用： ``` 用户：用费曼技巧帮我回顾一下[[机器学习中的过拟合]] ``` **执行流程**： 1. **读取知识源** - 从你的笔记中读取相关内容 2. **模拟教学** - 你向 AI 学生解释概念 3. **提问挑战** - AI 提出基础到深入的问题 4. **诊断分析** - AI 分析你的理解盲点 5. **生成建议** - 提供个性化学习建议和复习材料 ### 模式 2：薄弱点专项训练 针对已识别的薄弱环节进行强化： ``` 用户：针对昨天的薄弱点进行专项训练 ``` **执行流程**： 1. **读取历史记录** - 查看之前的诊断结果 2. **针对性提问** - 重点针对薄弱环节提问 3. **深度解析** - 提供详细的解释和示例 4. **生成练习** - 创建针对性练习题 ### 模式 3：知识体系梳理 帮助你建立知识间的联系： ``` 用户：帮我梳理一下深度学习的知识体系 ``` **执行流程**： 1. **搜索相关笔记** - 找到所有相关知识点 2. **构建知识图谱** - 分析概念间的关系 3. **识别缺失环节** - 发现知识体系中的空白 4. **生成学习路径** - 提供系统化的学习建议 ## 使用方法 ### 基本用法 **步骤 1：选择要回顾的知识** ``` 用户：费曼教练，帮我回顾[[决策树算法]] ``` **步骤 2：开始讲解** AI 会扮演一个好奇但完全不懂的学生，你需要用简单的语言向它解释。 **步骤 3：回答问题** AI 会提出各种问题，从基础到深入： - "什么是决策树？" - "信息增益是什么意思？" - "决策树和随机森林有什么区别？" - "过拟合怎么解决？" **步骤 4：查看诊断报告** 讲解结束后，AI 会生成诊断报告： - ✅ 理解良好的部分 - ⚠️ 需要加强的部分 - ❌ 理解有误的部分 - 📚 推荐的学习资源 ### 高级用法 **配置每日自动回顾** 在 `.opencode/config.toml` 中添加： ```toml [feynman-coach] enabled = true review_time = "09:00" # 每天上午9点触发 days_between_reviews = 1 # 每隔1天回顾一次 review_scope = "recent_notes" # 可选：recent_notes, random, tagged review_tags = ["#学习", "#重要"] # 如果 review_scope = "tagged" max_daily_concepts = 3 # 每天最多回顾3个概念 ``` **手动触发每日回顾** ``` 用户：/feynman daily-review ``` **查看学习统计** ``` 用户：/feynman stats ``` **导出复习卡片** ``` 用户：/feynman export-cards [[决策树算法]] ``` ## 输出格式 ### 诊断报告示例 ```markdown # 费曼学习诊断报告 ## 回顾主题：决策树算法 ### 📊 理解度评估 **总体评分：75/100** #### ✅ 理解良好的部分 (40%) - 决策树的基本概念和结构 - 分类和回归的区别 - 树的构建过程 #### ⚠️ 需要加强的部分 (45%) - **信息增益的计算原理** - 建议：复习熵和信息增益的数学公式 - 资源：[[信息论基础]] - **剪枝策略的选择** - 建议：理解预剪枝和后剪枝的适用场景 - 资源：[[模型正则化方法]] #### ❌ 理解有误的部分 (15%) - **基尼指数 vs 信息增益** - 误区：认为两者计算结果相同 - 纠正：基尼指数偏向多分类，信息增益更通用 - 建议：对比两者的数学定义和适用场景 ### 🎯 个性化学习建议 1. **立即行动** - 阅读 [[信息论基础]] 第3章 - 完成下方的针对性练习 2. **本周目标** - 理解信息增益的数学推导 - 能够手动计算简单数据集的信息增益 3. **长期规划** - 将决策树与其他模型对比（SVM、神经网络） - 学习集成方法（随机森林、XGBoost） ### 📝 针对性练习题 **练习 1：计算题** 给定数据集... 请计算属性 A 的信息增益。 **练习 2：应用题** 在以下场景中，你会选择哪种剪枝策略？为什么？ ... **练习 3：对比分析** 比较决策树和逻辑回归在以下方面的异同：... ### 🔗 相关知识链接 - [[信息论基础]] - [[模型评估指标]] - [[集成学习方法]] - [[特征工程技巧]] ### 📅 下次回顾建议 **建议时间**：3天后 **重点内容**：信息增益计算、剪枝策略 **预计时长**：20分钟 ``` ### 复习卡片格式 ```markdown # 决策树算法 - 复习卡片 ## 卡片 1：基础概念 **正面**：什么是决策树？ **背面**：决策树是一种... ## 卡片 2：核心算法 **正面**：ID3、C4.5、CART 的区别？ **背面**：... ## 卡片 3：常见问题 **正面**：决策树容易过拟合，如何解决？ **背面**：... ``` ## 自动触发机制 ### 配置说明 本 Skill 支持通过以下方式实现每日自动触发： #### 方式 1：使用系统定时任务（推荐） **Windows (PowerShell)**： ```powershell # 创建每日任务 $action = New-ScheduledTaskAction -Execute "opencode" -Argument "run /feynman daily-review" $trigger = New-ScheduledTaskTrigger -Daily -At 9am Register-ScheduledTask -Action $action -Trigger $trigger -TaskName "FeynmanDailyReview" -Description "每日费曼学习回顾" ``` **macOS/Linux (cron)**： ```bash # 编辑 crontab crontab -e # 添加每日9点执行 0 9 * * * cd /path/to/your/project && opencode run /feynman daily-review ``` #### 方式 2：使用 Obsidian 插件 如果你使用 Obsidian，可以安装 **Templater** 或 **Dataview** 插件，结合本 Skill 实现： 1. 创建每日笔记模板 2. 在模板中添加费曼回顾按钮 3. 点击按钮触发 Skill #### 方式 3：使用 GitHub Actions 如果你将笔记放在 GitHub 上，可以配置 GitHub Actions： ```yaml # .github/workflows/feynman-review.yml name: Daily Feynman Review on: schedule: - cron: '0 9 * * *' # 每天 UTC 9点 jobs: review: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: Run Feynman Coach run: | opencode run /feynman daily-review ``` ### 触发时行为 当自动触发时，费曼教练会： 1. **选择回顾内容** - 根据配置选择最近学习的笔记 - 或随机选择标记为 #复习 的笔记 - 或选择之前诊断出有薄弱点的笔记 2. **生成回顾任务** - 创建 Todo 列表 - 发送到 Obsidian 每日笔记 - 或显示通知提醒 3. **执行回顾流程** - 读取笔记内容 - 生成针对性问题 - 等待用户回答（交互式） - 或生成自测卡片（非交互式） ## 最佳实践 ### 学习节奏建议 - **新学知识**：学习当天进行第一次费曼回顾 - **短期巩固**：3天后进行第二次回顾 - **长期记忆**：1周后、1个月后分别回顾 - **定期梳理**：每月进行一次知识体系梳理 ### 提问技巧 **好的解释应该**： - 使用类比和生活化例子 - 避免专业术语，或解释术语 - 从简单到复杂，循序渐进 - 包含具体的例子和应用场景 **如果卡住了**： - 承认自己不懂的地方 - 回到原始材料重新学习 - 用更简单的方式重新解释 - 请求 AI 提供提示和引导 ### 知识管理建议 1. **标记重要概念** - 使用 `#费曼回顾` 标签 - 添加 `NextReview: 2025-02-20` 元数据 2. **建立知识链接** - 在笔记中添加 `RelatedNotes:` - 使用 Obsidian 的图谱视图 3. **记录学习历程** - 保存每次诊断报告 - 追踪理解度变化 - 记录常见误区 ## 故障排除 ### 常见问题 **Q: 自动触发没有工作？** A: 检查以下几点： - 定时任务是否正确配置 - opencode 是否在系统 PATH 中 - 项目路径是否正确 **Q: AI 提出的问题太简单/太难？** A: 可以在提问时说明你的水平： ``` 我是初学者，请从基础开始提问 ``` 或 ``` 我已经掌握基础，请深入提问 ``` **Q: 如何跳过某个知识点？** A: 在诊断报告中会提供跳过选项，或手动编辑笔记添加 `#跳过回顾` 标签。 **Q: 回顾历史记录保存在哪里？** A: 默认保存在 `Z_Utils/feynman-coach/history/` 目录下，按日期组织。 ## 进阶配置 ### 自定义评分标准 在 `SKILL.md` 同级目录创建 `config.json`： ```json { "scoring": { "clarity_weight": 0.3, "accuracy_weight": 0.4, "depth_weight": 0.2, "examples_weight": 0.1 }, "difficulty_levels": { "beginner": {"depth": "basic", "questions": 3}, "intermediate": {"depth": "medium", "questions": 5}, "advanced": {"depth": "deep", "questions": 7} } } ``` ### 集成其他工具 **与 Anki 集成**： ```bash # 导出复习卡片到 Anki opencode run /feynman export-anki [[决策树算法]] ``` **与 Notion 集成**： ```bash # 同步学习记录到 Notion opencode run /feynman sync-notion ``` ## 参考资源 - [费曼学习法原文](https://fs.blog/feyman-technique/) - [Obsidian 间隔重复插件](https://github.com/st3v3nmw/obsidian-spaced-repetition) - [Anki 记忆卡片软件](https://apps.ankiweb.net/) ## 版本历史 - v1.0 (2025-02-13) - 初始版本，支持基础费曼学习流程 - v1.1 (计划中) - 添加自动触发机制 - v1.2 (计划中) - 添加学习统计和可视化 - v1.3 (计划中) - 添加 Anki/Notion 集成 --- **提示**：本 Skill 需要配合 Obsidian 或其他笔记软件使用，确保你的知识库有良好的结构和链接关系，这样费曼教练才能发挥最大效果。

path: README.md
content: # 费曼学习法教练 - 安装和配置指南

## 快速开始

### 1. 安装依赖

```bash
# 可选：安装 toml 解析库以支持 .toml 配置文件
pip install tomli

# 可选：安装 win10toast 以获得更好的 Windows 通知体验
pip install win10toast
```

### 2. 配置自动触发

#### Windows (PowerShell)

以管理员身份运行 PowerShell：

```powershell
# 创建每日任务（上午9点执行）
$action = New-ScheduledTaskAction -Execute "python" -Argument "$PWD\skills\feynman-coach\scripts\daily_review.py"
$trigger = New-ScheduledTaskTrigger -Daily -At 9am
Register-ScheduledTask -Action $action -Trigger $trigger -TaskName "FeynmanDailyReview" -Description "每日费曼学习回顾"

# 验证任务是否创建成功
Get-ScheduledTask -TaskName "FeynmanDailyReview"
```

#### macOS/Linux (crontab)

```bash
# 编辑 crontab
crontab -e

# 添加每日9点执行（根据你的实际路径调整）
0 9 * * * cd /path/to/your/note/project && python skills/feynman-coach/scripts/daily_review.py

# 保存并退出
```

#### 使用 GitHub Actions（如果你的笔记在 GitHub 上）

创建 `.github/workflows/feynman-review.yml`：

```yaml
name: Daily Feynman Review

on:
  schedule:
    - cron: '0 9 * * *'  # 每天 UTC 9点
  workflow_dispatch:  # 允许手动触发

jobs:
  review:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      
      - name: Set up Python
        uses: actions/setup-python@v4
        with:
          python-version: '3.10'
      
      - name: Run Feynman Coach
        run: python skills/feynman-coach/scripts/daily_review.py
      
      - name: Commit and push if changed
        run: |
          git config --local user.email "[REDACTED_SECRET]"
          git config --local user.name "GitHub Action"
          git add Z_Utils/feynman-coach/daily-reviews/
          git diff --quiet && git diff --staged --quiet || git commit -m "Add daily Feynman review for $(date +%Y-%m-%d)"
          git push
```

### 3. 配置文件

在项目根目录创建 `.opencode/config.toml`：

```toml
[feynman-coach]
enabled = true
review_time = "09:00"
days_between_reviews = 1
review_scope = "recent_notes"  # 可选：recent_notes, random, tagged, weak_points
review_tags = ["#费曼回顾", "#学习", "#重要"]
max_daily_concepts = 3
output_format = "obsidian"  # obsidian 或 markdown
```

## 使用方法

### 手动触发回顾

```bash
# 基本用法
python skills/feynman-coach/scripts/daily_review.py

# 指定配置文件
python skills/feynman-coach/scripts/daily_review.py --config my-config.json

# 试运行（不保存文件）
python skills/feynman-coach/scripts/daily_review.py --dry-run

# 列出最近可回顾的笔记
python skills/feynman-coach/scripts/daily_review.py --list
```

### 在 Obsidian 中使用

1. 运行脚本生成每日回顾任务
2. 在 Obsidian 中打开生成的文件（位于 `Z_Utils/feynman-coach/daily-reviews/`）
3. 按照任务清单进行费曼学习回顾
4. 记录你的解释和理解自评

### 与 Opencode 集成

在 opencode 中使用：

```
用户：/feynman daily-review
```

或

```
用户：帮我用费曼技巧回顾一下[[机器学习]]
```

## 配置选项说明

| 选项 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| `enabled` | bool | true | 是否启用自动回顾 |
| `review_time` | string | "09:00" | 每日回顾时间（24小时制） |
| `days_between_reviews` | int | 1 | 每隔几天回顾一次 |
| `review_scope` | string | "recent_notes" | 回顾范围：recent_notes（最近笔记）、random（随机）、tagged（按标签）、weak_points（薄弱点） |
| `review_tags` | list | ["#费曼回顾"] | 如果 review_scope 为 tagged，则回顾带这些标签的笔记 |
| `max_daily_concepts` | int | 3 | 每天最多回顾几个概念 |
| `output_format` | string | "obsidian" | 输出格式：obsidian 或 markdown |

## 文件结构

```
skills/feynman-coach/
├── SKILL.md                    # Skill 核心文档
├── README.md                   # 本文件
├── scripts/
│   └── daily_review.py        # 每日回顾脚本
└── examples/                   # 使用示例（待添加）

Z_Utils/feynman-coach/          # 运行时生成的数据
├── daily-reviews/             # 每日回顾任务
│   ├── review-2025-02-13.md
│   └── review-2025-02-14.md
└── history/                   # 回顾历史记录
    ├── 2025-02-13-决策树算法.json
    └── 2025-02-14-神经网络.json
```

## 故障排除

### 1. 脚本无法运行

**问题**：`python: can't open file 'daily_review.py'`

**解决**：确保你在项目根目录运行脚本，或使用完整路径：
```bash
python "D:\lhj\Note\Note\skills\feynman-coach\scripts\daily_review.py"
```

### 2. 没有生成回顾任务

**问题**：运行脚本后没有看到生成的文件

**解决**：
- 检查是否有最近的笔记（7天内修改的）
- 尝试使用 `--list` 参数查看可回顾的笔记
- 检查 `Z_Utils/feynman-coach/daily-reviews/` 目录是否存在

### 3. 定时任务没有触发

**问题**：配置了定时任务但没有自动运行

**解决**：
- Windows：检查任务计划程序中的任务状态
- macOS/Linux：检查 crontab 是否正确配置，运行 `crontab -l` 查看

### 4. 通知没有显示

**问题**：运行完成但没有收到通知

**解决**：
- Windows：确保在图形界面环境下运行（不是在纯 SSH 会话中）
- 这是可选功能，不影响核心功能

## 进阶用法

### 自定义问题模板

编辑 `daily_review.py` 中的 `generate_review_questions` 方法，添加你自己的问题模板。

### 集成 Anki

（待实现）将复习卡片导出到 Anki：

```bash
python skills/feynman-coach/scripts/export_anki.py [[决策树算法]]
```

### 生成学习报告

（待实现）查看学习统计：

```bash
python skills/feynman-coach/scripts/generate_report.py --month 2025-02
```

## 更新日志

- v1.0.0 (2025-02-13)
  - 初始版本
  - 支持基本的费曼学习回顾流程
  - 支持自动定时触发
  - 支持多种回顾模式

## 贡献

欢迎提交 Issue 和 PR！

## 许可证

MIT License


path: scripts/daily_review.py
content: #!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
费曼学习法教练 - 每日自动回顾脚本

功能：
1. 根据配置选择需要回顾的笔记
2. 生成费曼学习问题
3. 创建 Obsidian 每日笔记中的回顾任务
4. 发送通知提醒

使用方法：
    python daily_review.py [--config path/to/config.json]

配置说明：
    在项目根目录的 .opencode/config.toml 中添加：

    [feynman-coach]
    enabled = true
    review_time = "09:00"
    days_between_reviews = 1
    review_scope = "recent_notes"  # recent_notes, random, tagged, weak_points
    review_tags = ["#学习", "#重要"]
    max_daily_concepts = 3
    output_format = "obsidian"  # obsidian, markdown, anki
"""

import os
import sys
import json
import random
import argparse
from datetime import datetime, timedelta
from pathlib import Path
from typing import List, Dict, Optional

# 配置默认值
DEFAULT_CONFIG = {
    "enabled": True,
    "review_time": "09:00",
    "days_between_reviews": 1,
    "review_scope": "recent_notes",  # recent_notes, random, tagged, weak_points
    "review_tags": ["#费曼回顾", "#学习"],
    "max_daily_concepts": 3,
    "output_format": "obsidian",
    "history_dir": "Z_Utils/feynman-coach/history",
    "vault_path": ".",  # 相对于脚本的位置
}


class FeynmanCoach:
    """费曼学习法教练核心类"""

    def __init__(self, config_path: Optional[str] = None):
        self.config = self._load_config(config_path)
        self.vault_path = Path(self.config.get("vault_path", "."))
        self.history_dir = Path(
            self.config.get("history_dir", "Z_Utils/feynman-coach/history")
        )
        self.history_dir.mkdir(parents=True, exist_ok=True)

    def _load_config(self, config_path: Optional[str]) -> Dict:
        """加载配置文件"""
        # 首先尝试从 .opencode/config.toml 读取
        opencode_config = Path(".opencode/config.toml")
        if opencode_config.exists():
            try:
                # Python 3.11+ 使用 tomllib，否则使用 tomli
                try:
                    import tomllib
                except ImportError:
                    import tomli as tomllib

                with open(opencode_config, "rb") as f:
                    config = tomllib.load(f)
                    if "feynman-coach" in config:
                        return {**DEFAULT_CONFIG, **config["feynman-coach"]}
            except ImportError:
                print("警告：未安装 toml 解析库，使用默认配置")
                print("提示：运行 'pip install tomli' 以支持 .toml 配置文件")
            except Exception as e:
                print(f"警告：读取 .opencode/config.toml 失败: {e}")

        # 然后尝试从指定路径读取
        if config_path and Path(config_path).exists():
            with open(config_path, "r", encoding="utf-8") as f:
                return {**DEFAULT_CONFIG, **json.load(f)}

        # 使用默认配置
        return DEFAULT_CONFIG.copy()

    def select_notes_for_review(self) -> List[Dict]:
        """根据配置选择需要回顾的笔记"""
        scope = self.config.get("review_scope", "recent_notes")
        max_concepts = self.config.get("max_daily_concepts", 3)

        if scope == "recent_notes":
            return self._get_recent_notes(days=7, limit=max_concepts)
        elif scope == "random":
            return self._get_random_notes(limit=max_concepts)
        elif scope == "tagged":
            tags = self.config.get("review_tags", ["#费曼回顾"])
            return self._get_tagged_notes(tags, limit=max_concepts)
        elif scope == "weak_points":
            return self._get_weak_points_notes(limit=max_concepts)
        else:
            return self._get_recent_notes(days=7, limit=max_concepts)

    def _get_recent_notes(self, days: int = 7, limit: int = 3) -> List[Dict]:
        """获取最近修改的笔记"""
        cutoff_date = datetime.now() - timedelta(days=days)
        notes = []

        # 搜索所有 markdown 文件
        for md_file in self.vault_path.rglob("*.md"):
            try:
                stat = md_file.stat()
                mtime = datetime.fromtimestamp(stat.st_mtime)

                if mtime >= cutoff_date:
                    # 读取文件内容获取标题
                    content = md_file.read_text(encoding="utf-8", errors="ignore")
                    title = self._extract_title(content) or md_file.stem

                    notes.append(
                        {
                            "path": str(md_file.relative_to(self.vault_path)),
                            "title": title,
                            "mtime": mtime.isoformat(),
                            "size": stat.st_size,
                        }
                    )
            except Exception as e:
                print(f"警告：读取文件 {md_file} 失败: {e}")
                continue

        # 按修改时间排序，取最新的
        notes.sort(key=lambda x: x["mtime"], reverse=True)
        return notes[:limit]

    def _get_random_notes(self, limit: int = 3) -> List[Dict]:
        """随机选择笔记"""
        all_notes = []

        for md_file in self.vault_path.rglob("*.md"):
            try:
                content = md_file.read_text(encoding="utf-8", errors="ignore")
                title = self._extract_title(content) or md_file.stem

                all_notes.append(
                    {"path": str(md_file.relative_to(self.vault_path)), "title": title}
                )
            except Exception:
                continue

        if len(all_notes) <= limit:
            return all_notes

        return random.sample(all_notes, limit)

    def _get_tagged_notes(self, tags: List[str], limit: int = 3) -> List[Dict]:
        """获取带特定标签的笔记"""
        tagged_notes = []

        for md_file in self.vault_path.rglob("*.md"):
            try:
                content = md_file.read_text(encoding="utf-8", errors="ignore")

                # 检查是否包含标签
                if any(tag in content for tag in tags):
                    title = self._extract_title(content) or md_file.stem

                    tagged_notes.append(
                        {
                            "path": str(md_file.relative_to(self.vault_path)),
                            "title": title,
                            "tags": [tag for tag in tags if tag in content],
                        }
                    )
            except Exception:
                continue

        # 随机选择
        if len(tagged_notes) <= limit:
            return tagged_notes

        return random.sample(tagged_notes, limit)

    def _get_weak_points_notes(self, limit: int = 3) -> List[Dict]:
        """获取之前诊断出有薄弱点的笔记"""
        weak_notes = []

        # 读取历史记录
        for history_file in self.history_dir.glob("*.json"):
            try:
                with open(history_file, "r", encoding="utf-8") as f:
                    record = json.load(f)

                    # 检查是否有薄弱点
                    if record.get("weak_points") and len(record["weak_points"]) > 0:
                        weak_notes.append(
                            {
                                "path": record.get("note_path", ""),
                                "title": record.get("title", "Unknown"),
                                "weak_points_count": len(record["weak_points"]),
                                "last_review": record.get("timestamp", ""),
                            }
                        )
            except Exception:
                continue

        # 按薄弱点数量排序
        weak_notes.sort(key=lambda x: x["weak_points_count"], reverse=True)
        return weak_notes[:limit]

    def _extract_title(self, content: str) -> Optional[str]:
        """从 markdown 内容中提取标题"""
        lines = content.split("\n")

        # 首先尝试从 YAML frontmatter 中提取
        if lines and lines[0].strip() == "---":
            for i, line in enumerate(lines[1:], 1):
                if line.strip() == "---":
                    break
                if line.startswith("theme:"):
                    return line.split(":", 1)[1].strip()

        # 然后尝试从第一个 # 标题提取
        for line in lines:
            if line.startswith("# "):
                return line[2:].strip()

        return None

    def generate_review_questions(self, note_path: str) -> List[str]:
        """为笔记生成费曼学习问题"""
        try:
            content = (self.vault_path / note_path).read_text(
                encoding="utf-8", errors="ignore"
            )
        except Exception:
            content = ""

        # 基于内容生成问题模板
        questions = [
            f"请用一句话解释 [[{Path(note_path).stem}]] 的核心概念",
            "这个概念与什么生活例子最相似？请用类比说明",
            "如果向一个完全不懂的人解释，你会怎么说？",
            "这个概念的关键组成部分有哪些？",
            "在实际应用中，这个概念如何发挥作用？",
            "这个概念容易与什么混淆？它们的区别是什么？",
            "你能举一个具体的例子来说明吗？",
        ]

        # 根据内容长度调整问题数量
        if len(content) < 500:
            return questions[:3]
        elif len(content) < 1500:
            return questions[:5]
        else:
            return questions

    def create_daily_review_task(self, notes: List[Dict]) -> str:
        """创建每日回顾任务"""
        today = datetime.now().strftime("%Y-%m-%d")
        output_format = self.config.get("output_format", "obsidian")

        if output_format == "obsidian":
            return self._create_obsidian_task(notes, today)
        elif output_format == "markdown":
            return self._create_markdown_task(notes, today)
        else:
            return self._create_obsidian_task(notes, today)

    def _create_obsidian_task(self, notes: List[Dict], date: str) -> str:
        """创建 Obsidian 格式的回顾任务"""
        task_content = f"""---
theme: 费曼学习回顾 - {date}
date: {date}
time: 09:00
tags:
  - Record/费曼回顾
---

# 🧠 费曼学习每日回顾 - {date}

> 💡 **费曼学习法**：如果你不能用简单的语言解释某件事，那你并没有真正理解它。

## 📋 今日回顾清单

"""

        for i, note in enumerate(notes, 1):
            questions = self.generate_review_questions(note["path"])
            question_list = "\n".join(
                [f"   {j + 1}. {q}" for j, q in enumerate(questions)]
            )

            task_content += f"""### {i}. [[{note["title"]}]]

**文件路径**：`{note["path"]}`

**费曼挑战问题**：
{question_list}

**我的解释**：
（在这里写下你的解释...）

**理解自评**：
- [ ] 完全理解，可以清晰解释
- [ ] 基本理解，但有些地方模糊
- [ ] 不太理解，需要重新学习

**薄弱环节记录**：
（AI 诊断后会在这里记录...）

---

"""

        task_content += f"""## 📊 今日学习统计

- **回顾概念数**：{len(notes)}
- **预计用时**：{len(notes) * 15} 分钟
- **完成状态**：
  - [ ] 完成所有回顾
  - [ ] 记录了薄弱环节
  - [ ] 生成了复习卡片

## 🎯 明日建议

（根据今日回顾情况自动生成...）

---

**触发时间**：{datetime.now().strftime("%Y-%m-%d %H:%M")}  
**配置模式**：{self.config.get("review_scope", "recent_notes")}
"""

        return task_content

    def _create_markdown_task(self, notes: List[Dict], date: str) -> str:
        """创建标准 Markdown 格式的回顾任务"""
        # 简化版本，不含 Obsidian 特定语法
        task_content = f"""# 费曼学习回顾 - {date}

## 今日回顾清单

"""

        for i, note in enumerate(notes, 1):
            questions = self.generate_review_questions(note["path"])
            question_list = "\n".join(
                [f"{j + 1}. {q}" for j, q in enumerate(questions)]
            )

            task_content += f"""### {i}. {note["title"]}

**费曼挑战问题**：
{question_list}

---

"""

        return task_content

    def save_review_task(self, content: str, date: str) -> Path:
        """保存回顾任务到文件"""
        # 保存到每日回顾目录
        review_dir = Path("Z_Utils/feynman-coach/daily-reviews")
        review_dir.mkdir(parents=True, exist_ok=True)

        output_file = review_dir / f"review-{date}.md"
        output_file.write_text(content, encoding="utf-8")

        # 同时保存到 Obsidian 日记（如果存在）
        daily_notes_dir = Path("3_flomo卡片笔记")  # 或其他日记目录
        if daily_notes_dir.exists():
            daily_file = daily_notes_dir / f"{date}.md"
            if daily_file.exists():
                # 追加到现有日记
                existing = daily_file.read_text(encoding="utf-8", errors="ignore")
                daily_file.write_text(existing + "\n\n" + content, encoding="utf-8")
            else:
                daily_file.write_text(content, encoding="utf-8")

        return output_file

    def send_notification(self, message: str):
        """发送通知提醒"""
        # Windows
        if sys.platform == "win32":
            try:
                # 尝试使用 win10toast 发送系统通知
                from win10toast import ToastNotifier

                toaster = ToastNotifier()
                toaster.show_toast("费曼教练", message, duration=10)
            except ImportError:
                # 如果没有安装 win10toast，使用 PowerShell 通知
                try:
                    import subprocess

                    subprocess.run(
                        [
                            "powershell",
                            "-Command",
                            f"Add-Type -AssemblyName System.Windows.Forms; "
                            f"[System.Windows.Forms.MessageBox]::Show('{message}', '费曼教练')",
                        ],
                        check=False,
                    )
                except Exception:
                    print(f"[通知] {message}")

        # macOS
        elif sys.platform == "darwin":
            os.system(
                f'osascript -e \'display notification "{message}" with title "费曼教练"\''
            )

        # Linux
        else:
            os.system(f'notify-send "费曼教练" "{message}"')

    def run_daily_review(self):
        """执行每日回顾流程"""
        print("🧠 费曼学习教练 - 每日回顾")
        print("=" * 50)

        # 1. 选择笔记
        print("\n📚 正在选择今日回顾内容...")
        notes = self.select_notes_for_review()

        if not notes:
            print("⚠️ 没有找到合适的笔记进行回顾")
            return

        print(f"✅ 已选择 {len(notes)} 个概念：")
        for note in notes:
            print(f"   - {note['title']}")

        # 2. 生成回顾任务
        print("\n📝 正在生成回顾任务...")
        task_content = self.create_daily_review_task(notes)

        # 3. 保存任务
        today = datetime.now().strftime("%Y-%m-%d")
        output_file = self.save_review_task(task_content, today)
        print(f"✅ 回顾任务已保存到：{output_file}")

        # 4. 发送通知
        self.send_notification(
            f"今日费曼回顾已准备就绪！共 {len(notes)} 个概念等待复习。"
        )

        print("\n✨ 每日回顾任务已生成！")
        print(f"📄 文件位置：{output_file}")
        print(
            "\n💡 提示：使用 Obsidian 打开查看完整任务，或运行 'opencode' 开始交互式回顾。"
        )


def main():
    parser = argparse.ArgumentParser(description="费曼学习法教练 - 每日自动回顾")
    parser.add_argument("--config", "-c", help="配置文件路径")
    parser.add_argument(
        "--dry-run", "-d", action="store_true", help="试运行，不保存文件"
    )
    parser.add_argument(
        "--list", "-l", action="store_true", help="列出最近可回顾的笔记"
    )

    args = parser.parse_args()

    # 初始化教练
    coach = FeynmanCoach(args.config)

    if args.list:
        # 只列出笔记，不生成任务
        print("📚 最近可回顾的笔记：")
        notes = coach.select_notes_for_review()
        for i, note in enumerate(notes, 1):
            print(f"{i}. {note['title']} ({note.get('path', 'N/A')})")
        return

    if args.dry_run:
        print("🔍 试运行模式（不会保存文件）")
        notes = coach.select_notes_for_review()
        print(f"\n将会选择以下 {len(notes)} 个笔记：")
        for note in notes:
            print(f"  - {note['title']}")
        return

    # 执行每日回顾
    coach.run_daily_review()


if __name__ == "__main__":
    main()


path: examples/usage_examples.md
content: # 费曼学习法教练 - 使用示例

## 示例 1：基础使用流程

### 场景
你昨天学习了决策树算法，今天想要巩固理解。

### 交互流程

```
用户：用费曼技巧帮我回顾一下[[决策树算法]]

AI（费曼教练）：
好的！我是你的费曼学习教练。现在我将扮演一个对机器学习完全不懂的初学者，请你用简单的语言向我解释"决策树算法"。

让我们开始吧！

---

**🎓 学生提问 1/7**

"你好！我听说你在学习决策树，能告诉我什么是决策树吗？它和我们平时看到的树有什么关系？"

---

请用简单的语言向我解释（就像教一个完全不懂的人）：

用户：
决策树就像是你做决策时画的一张流程图。比如说你要决定周末要不要去郊游，你可能会先看"天气好不好"，如果不好就待在家，如果好再看"有没有朋友一起去"...这样一层层问下去，最后就得到决定。计算机用这种方法来做分类预测。

AI（费曼教练）：
哇，这个例子很生动！用"周末郊游"来解释真的很形象。让我继续提问...

**🎓 学生提问 2/7**

"那计算机怎么知道要先问'天气'，而不是先问'有没有朋友'呢？这个顺序是怎么定的？"

[继续交互...]

---

**📊 费曼学习诊断报告**

## 理解度评估

**总体评分：82/100** ⭐⭐⭐⭐

### ✅ 理解良好的部分
- 能用生活化的例子解释核心概念
- 清楚说明决策树的决策流程
- 理解分类预测的应用场景

### ⚠️ 需要加强的部分
- **信息增益的计算原理**
  - 建议：了解熵的概念和计算公式
  - 资源：[[信息论基础]]

- **剪枝策略**
  - 建议：理解为什么要剪枝，以及预剪枝和后剪枝的区别

### ❌ 理解有误的部分
- 暂无

### 🎯 个性化学习建议

1. **立即行动**
   - 阅读 [[信息论基础]] 第3章
   - 尝试手动计算一个简单的信息增益例子

2. **本周目标**
   - 理解决策树与其他分类器（如SVM）的区别
   - 学习随机森林的基本概念

### 📝 针对性练习题

**练习 1**：给定以下数据集，计算"年龄"属性的信息增益...

**练习 2**：在以下场景中，你会选择预剪枝还是后剪枝？为什么？...

---

💡 **下次回顾建议**：3天后，重点练习信息增益计算
```

## 示例 2：每日自动回顾

### 配置

在项目根目录创建 `.opencode/config.toml`：

```toml
[feynman-coach]
enabled = true
review_time = "09:00"
days_between_reviews = 1
review_scope = "recent_notes"
max_daily_concepts = 3
output_format = "obsidian"
```

### 定时任务设置（Windows）

```powershell
# 创建每日9点的定时任务
$action = New-ScheduledTaskAction -Execute "python" -Argument "$PWD\skills\feynman-coach\scripts\daily_review.py"
$trigger = New-ScheduledTaskTrigger -Daily -At 9am
Register-ScheduledTask -Action $action -Trigger $trigger -TaskName "FeynmanDailyReview" -Description "每日费曼学习回顾"
```

### 生成的每日回顾任务示例

文件位置：`Z_Utils/feynman-coach/daily-reviews/review-2025-02-13.md`

```markdown
---
theme: 费曼学习回顾 - 2025-02-13
date: 2025-02-13
time: 09:00
tags:
  - Record/费曼回顾
---

# 🧠 费曼学习每日回顾 - 2025-02-13

> 💡 **费曼学习法**：如果你不能用简单的语言解释某件事，那你并没有真正理解它。

## 📋 今日回顾清单

### 1. [[决策树算法]]

**文件路径**：`1_我的创作/A-决策树算法学习笔记.md`

**费曼挑战问题**：
   1. 请用一句话解释 决策树算法 的核心概念
   2. 这个概念与什么生活例子最相似？请用类比说明
   3. 如果向一个完全不懂的人解释，你会怎么说？
   4. 这个概念的关键组成部分有哪些？
   5. 在实际应用中，这个概念如何发挥作用？
   6. 这个概念容易与什么混淆？它们的区别是什么？
   7. 你能举一个具体的例子来说明吗？

**我的解释**：
（在这里写下你的解释...）

**理解自评**：
- [ ] 完全理解，可以清晰解释
- [ ] 基本理解，但有些地方模糊
- [ ] 不太理解，需要重新学习

**薄弱环节记录**：
（AI 诊断后会在这里记录...）

---

### 2. [[神经网络基础]]

[类似结构...]

---

### 3. [[正则化方法]]

[类似结构...]

---

## 📊 今日学习统计

- **回顾概念数**：3
- **预计用时**：45 分钟
- **完成状态**：
  - [ ] 完成所有回顾
  - [ ] 记录了薄弱环节
  - [ ] 生成了复习卡片

## 🎯 明日建议

根据今日回顾情况，建议明天重点复习：
- 信息增益的数学原理
- L1 和 L2 正则化的区别

---

**触发时间**：2025-02-13 09:00  
**配置模式**：recent_notes
```

## 示例 3：薄弱点专项训练

### 场景
之前的回顾中，你发现对"信息增益"理解不够深入。

### 交互流程

```
用户：针对信息增益这个薄弱点进行专项训练

AI（费曼教练）：
好的！我注意到你之前在学习决策树时，对"信息增益"这个概念的掌握度是 60%。让我们进行专项强化训练！

---

**🎯 专项训练：信息增益**

**前置知识检查**：

在讲信息增益之前，我想确认一下：
1. 你知道什么是"熵"吗？能解释一下吗？
2. 为什么我们要用熵来衡量数据的不确定性？

请用自己的话解释这两个概念。

---

用户：
熵就是描述数据混乱程度的一个指标。如果数据很纯，比如全是正例，那熵就低；如果数据很混乱，正负例各占一半，那熵就高。

AI（费曼教练）：
很好！理解得很到位。那现在我们来深入信息增益...

**核心概念讲解**：

信息增益 = 分裂前的熵 - 分裂后的加权平均熵

让我用一个具体的例子来说明：

假设我们有以下数据集：
[表格展示]

现在我们要计算"天气"这个属性的信息增益...

[详细讲解和计算过程]

---

**📝 专项练习**

**练习 1**：计算题
给定数据集...
请计算属性 A 的信息增益。

**练习 2**：应用题
在以下场景中，你会选择哪个属性作为第一个分裂节点？为什么？

**练习 3**：对比分析
信息增益和信息增益率有什么区别？什么时候应该用后者？

---

**✅ 训练完成！**

本次专项训练完成。建议：
1. 完成上述3道练习题
2. 3天后再次回顾信息增益概念
3. 阅读 [[C4.5算法]] 了解信息增益率
```

## 示例 4：知识体系梳理

### 场景
你想要梳理深度学习的知识体系，找出知识盲区。

### 交互流程

```
用户：帮我梳理一下深度学习的知识体系

AI（费曼教练）：
好的！我将帮你梳理深度学习的知识体系。让我先搜索你的笔记库...

---

**📚 发现的相关笔记**：

1. [[神经网络基础]] - 修改于 2天前
2. [[反向传播算法]] - 修改于 3天前
3. [[卷积神经网络]] - 修改于 5天前
4. [[优化算法]] - 修改于 1周前
5. [[正则化方法]] - 修改于 2天前
6. [[循环神经网络]] - 修改于 2周前

---

**🗺️ 知识体系图谱**

```
深度学习
├── 基础组件
│   ├── 神经元与激活函数 ✓
│   ├── 前向传播 ✓
│   └── 反向传播 ✓
├── 网络架构
│   ├── CNN (卷积神经网络) ✓
│   ├── RNN (循环神经网络) ⚠️ (2周未复习)
│   └── Transformer ? (未找到相关笔记)
├── 训练技巧
│   ├── 优化算法 (SGD, Adam) ✓
│   ├── 正则化 (L1, L2, Dropout) ✓
│   └── 批归一化 ? (未找到相关笔记)
└── 应用实践
    ├── 图像分类 ✓
    ├── 目标检测 ? (未找到相关笔记)
    └── 自然语言处理 ? (未找到相关笔记)
```

**图例**：
- ✓ 已学习且近期复习
- ⚠️ 已学习但需复习
- ? 知识空白

---

**🔍 知识盲区识别**

基于你的笔记分析，发现以下知识空白：

1. **Transformer 架构**
   - 重要性：⭐⭐⭐⭐⭐
   - 建议：这是当前最重要的架构，建议优先学习
   - 资源：[[Attention Is All You Need]]

2. **批归一化 (Batch Normalization)**
   - 重要性：⭐⭐⭐⭐
   - 建议：训练深度网络的关键技术
   - 资源：[[批归一化原理解析]]

3. **目标检测**
   - 重要性：⭐⭐⭐
   - 建议：如果做计算机视觉，这是必学内容
   - 资源：[[YOLO算法]], [[R-CNN系列]]

---

**📈 个性化学习路径**

根据你的知识现状，建议按以下顺序学习：

**第1周**：Transformer 基础
- 学习 Self-Attention 机制
- 理解 Multi-Head Attention
- 实现一个简单的 Transformer

**第2周**：批归一化与高级训练技巧
- 理解 BN 的原理
- 学习 Layer Norm、Group Norm
- 对比各种归一化方法

**第3周**：复习与整合
- 回顾所有基础概念
- 建立完整的知识图谱
- 完成综合练习

---

💡 **提示**：我已经将这些建议保存到你的笔记中，并设置了复习提醒。
```

## 示例 5：与 Obsidian 集成

### 在 Obsidian 日记中使用

1. **运行每日回顾脚本**
   ```bash
   python skills/feynman-coach/scripts/daily_review.py
   ```

2. **在 Obsidian 中打开生成的文件**
   - 文件位置：`Z_Utils/feynman-coach/daily-reviews/review-2025-02-13.md`

3. **完成回顾任务**
   - 阅读问题
   - 在"我的解释"部分写下答案
   - 勾选"理解自评"
   - 记录薄弱环节

4. **使用 Dataview 查看统计**

   创建一个查询页面：
   ```markdown
   # 费曼学习统计
   
   ## 本月回顾记录
   
   ```dataview
   TABLE date, tags
   FROM "Z_Utils/feynman-coach/daily-reviews"
   WHERE date > date(today) - dur(30 days)
   SORT date DESC
   ```
   
   ## 薄弱环节统计
   
   ```dataview
   TABLE concept, weakness_type, severity
   FROM "Z_Utils/feynman-coach/history"
   WHERE severity = "high"
   SORT date DESC
   ```
   ```

## 示例 6：命令行使用

### 列出可回顾的笔记

```bash
$ python skills/feynman-coach/scripts/daily_review.py --list

📚 最近可回顾的笔记：
1. 决策树算法 (1_我的创作/A-决策树算法学习笔记.md)
2. 神经网络基础 (1_我的创作/A-神经网络基础.md)
3. 正则化方法 (1_我的创作/A-正则化方法.md)
```

### 试运行（不保存文件）

```bash
$ python skills/feynman-coach/scripts/daily_review.py --dry-run

🔍 试运行模式（不会保存文件）

将会选择以下 3 个笔记：
  - 决策树算法
  - 神经网络基础
  - 正则化方法
```

### 使用自定义配置

```bash
$ python skills/feynman-coach/scripts/daily_review.py --config my-config.json

🧠 费曼学习教练 - 每日回顾
==================================================

📚 正在选择今日回顾内容...
✅ 已选择 3 个概念：
   - 决策树算法
   - 神经网络基础
   - 正则化方法

📝 正在生成回顾任务...
✅ 回顾任务已保存到：Z_Utils\feynman-coach\daily-reviews\review-2025-02-13.md

✨ 每日回顾任务已生成！
📄 文件位置：Z_Utils\feynman-coach\daily-reviews\review-2025-02-13.md

💡 提示：使用 Obsidian 打开查看完整任务，或运行 'opencode' 开始交互式回顾。
```

## 更多使用场景

### 考试前复习
```
用户：我下周有机器学习考试，帮我制定复习计划

AI：基于你的笔记，我建议...
```

### 演讲前准备
```
用户：我要给同事讲解 Docker，帮我准备一下

AI：好的！让我用费曼技巧帮你准备...
```

### 学习新领域
```
用户：我想学习强化学习，从哪里开始？

AI：让我先了解你现有的知识基础...
```

---

**提示**：更多示例和用法请参考 `SKILL.md` 文档。


Security scan verdicts — ClawScan: clean | static analysis: clean | VirusTotal: clean | SkillSpector: suspicious (CRITICAL)