360 Secure SkillHub
360 安全技能中心

Algernon Review

在 OpenAlgernon 中运行交互式闪卡复习:从本地 SQLite 数据库读取到期卡片,按 FSRS-4.5 规则更新稳定性、难度与下次到期日,对论述题/论证题作答做 AI 评估并生成纠错卡,最后检查 N1→N2→N3 晋升、输出会话小结并追加会话日志。

antoniovfranco
antoniovfranco
热度 81.50
最近更新 2026-05-11 17:32:38
分类:知识依赖:代码执行 / 读写文件 / 内部调用大模型应用场景:教学辅导 / 测验 / 日程安排

安装技能

复制下面的话术发给你的 Agent,它会通过 secure-skills 检索并安装该技能。

执行命令安装此 skill: npx secure-skills-cli add algernon-review
Metadata
name
algernon-review
version
1.0.0
description
FSRS-4.5 flashcard review session for OpenAlgernon. Use when the user runs `/algernon review`, says "revisar flashcards", "quero revisar", "cards em atraso", "modo revisao", "review session", or asks to practice due cards. Handles all card types (flashcard, dissertative, argumentative), AI evaluation of open-ended answers, automatic FSRS scheduling, N1/N2/N3 promotion, and correction card generation.

algernon-review

You run the interactive flashcard review session with FSRS-4.5 spaced repetition. You handle flashcards (binary reveal), dissertative cards (AI-graded), and argumentative cards (AI-graded). At the end, you check promotion eligibility and save the session.

Constants

ALGERNON_HOME="${ALGERNON_HOME:-$HOME/.openalgernon}"
DB="${ALGERNON_HOME}/data/study.db"

FSRS-4.5 Parameters

  • DECAY = -0.5, FACTOR = 0.2346
  • Stability (S) = days to reach 90% retention
  • Grades: 1 = Again, 3 = Good

Step 1 — Fetch Due Cards

sqlite3 "$DB" \
  "SELECT c.id, c.type, c.front, c.back, c.tags, c.source_title, c.deck_id,
          cs.stability, cs.reps, cs.state
   FROM cards c
   JOIN card_state cs ON cs.card_id = c.id
   JOIN decks d ON d.id = c.deck_id
   JOIN materials m ON m.id = d.material_id
   WHERE cs.due_date <= date('now')
   [AND m.slug = 'SLUG']
   ORDER BY cs.due_date ASC
   LIMIT 50;"

(Include AND m.slug = 'SLUG' only if a specific slug was provided.)

If no cards due: "No cards due for review. Great job staying on top of it." and stop.

Display: "Starting review: N cards due."

Step 2 — Review Loop

Flashcards (type = 'flashcard')

  1. Show front. AskUserQuestion options: ["Show answer"]
  2. Show back. AskUserQuestion options: ["Again", "Good"]
  3. Run FSRS update (see Step 3).

Dissertative and Argumentative Cards

  1. Show front. AskUserQuestion options: ["Ready to answer"]
  2. AskUserQuestion: "Type your answer:" (free text)
  3. Evaluate the response against the reference answer (card back):
    • Dissertative: check accuracy of key points, completeness
    • Argumentative: check that both sides are represented, trade-offs identified
    • Output: brief feedback + suggested grade (1 or 3) + optional MISCONCEPTION note
  4. Show evaluator feedback + reference answer. AskUserQuestion options: ["Again", "Good"] (Use the user's button choice, not the AI suggestion.)
  5. Run FSRS update using the user's chosen grade.
  6. If a MISCONCEPTION was detected, create a correction card:
    sqlite3 "$DB" \
      "INSERT INTO cards (deck_id, type, front, back, tags)
       VALUES (DECK_ID, 'flashcard',
               'CORRECTION: MISCONCEPTION_QUESTION',
               'CORRECT_EXPLANATION',
               '[\"[correction]\",\"[N1]\"]');
       INSERT INTO card_state (card_id, due_date)
       VALUES (last_insert_rowid(), date('now'));"
    

Step 3 — FSRS Scheduling

For each graded card, compute new values and update card_state.

Read current state:

sqlite3 "$DB" \
  "SELECT stability, difficulty, reps, lapses, state, last_review
   FROM card_state WHERE card_id = CARD_ID;"

Compute elapsed days (if last_review is not NULL):

sqlite3 "$DB" \
  "SELECT ROUND(julianday('now') - julianday('LAST_REVIEW'), 2) AS elapsed;"

State transitions:

State Grade New stability New difficulty New state Interval
new Good 0.4 0.3 review 1 day
new Again 0.1 0.4 learning 1 day
learning Good stability * 1.5 MAX(0.1, difficulty - 0.05) review MAX(1, ROUND(S))
learning Again stability (unchanged) MIN(1.0, difficulty + 0.1) learning 1 day
relearning Good stability * 1.5 MAX(0.1, difficulty - 0.05) review MAX(1, ROUND(S))
relearning Again stability (unchanged) MIN(1.0, difficulty + 0.1) relearning 1 day
review Good S * EXP(0.9*(1-R)) MAX(0.1, difficulty - 0.05) review MAX(1, ROUND(S))
review Again MAX(0.1, stability * 0.2) MIN(1.0, difficulty + 0.1) relearning 1 day, lapses+1

For review+Good, compute retrievability first:

sqlite3 "$DB" \
  "SELECT EXP(LN(0.9) * ELAPSED / STABILITY) AS R;"

Update:

sqlite3 "$DB" \
  "UPDATE card_state SET
     stability   = NEW_S,
     difficulty  = NEW_D,
     due_date    = date('now', '+' || INTERVAL || ' days'),
     last_review = datetime('now'),
     reps        = reps + 1,
     lapses      = NEW_LAPSES,
     state       = 'NEW_STATE'
   WHERE card_id = CARD_ID;
   INSERT INTO reviews (card_id, grade, scheduled_days, elapsed_days)
   VALUES (CARD_ID, GRADE, INTERVAL, ELAPSED);"

Step 4 — Promotion Check (after all cards)

For each card reviewed with grade = Good where reps >= 5:

sqlite3 "$DB" \
  "SELECT c.id, c.tags, c.deck_id, cs.reps
   FROM cards c JOIN card_state cs ON cs.card_id = c.id
   WHERE c.id = CARD_ID AND cs.reps >= 5;"

If reps >= 5 and tags contain [N1], check deck retention over last 7 days:

sqlite3 "$DB" \
  "SELECT CAST(SUM(CASE WHEN grade=3 THEN 1 ELSE 0 END) AS REAL) / COUNT(id) AS retention
   FROM reviews r JOIN cards c ON c.id = r.card_id
   WHERE c.deck_id = DECK_ID AND r.reviewed_at >= datetime('now', '-7 days');"

If retention >= 0.9:

  • Generate a deeper N2 version of the card (N2: differentiator + when to use + main trade-off).
  • Insert as new card with tag [N2], due today.
  • Apply same logic for [N2] cards: promote to N3 (full technical depth, production nuances, edge cases).

Step 5 — Session Summary

Session complete.
Cards reviewed: N
Again: X  |  Good: Y
Retention this session: Z%
Next review: [earliest due_date from card_state]

Append to today's conversation log:

echo "[HH:MM] review session | Cards: N | Retention: Z% | Promotions: P" \
  >> "${ALGERNON_HOME}/memory/conversations/YYYY-MM-DD.md"