はじめに:「環境は整っている。なのに動けない」
AWS SAA、基本情報技術者試験、応用情報……
エンジニアなら一度は「今年こそ」と思った資格があるはずだ。
参考書を買って、アプリを入れて、「よし、明日から始めよう」と思った次の日に別の仕事が入る。翌週また「よし」と思う。繰り返す。
私も長い間その繰り返しをしていた。
ただ、最近気づいたことがある。問題は「やる気がない」ことではなかった。「始めるまでのコスト」が積み重なって、結局何もしないという選択が一番ラクになっていた。
今回は、そのコストを下げるためにCobo Memoというアプリに実装した機能を紹介しながら、「こういう環境があればエンジニアの資格勉強は回せる」という話を書く。
資格勉強が続かない理由を分解する
続かない理由はシンプルだ。
1. 何を覚えるか考える
2. カードを作る
3. 復習のスケジュールを管理する
4. また1に戻る
この4ステップのうち、1〜3が全部コストだ。勉強そのもの(問題を解いて定着させること)は4のうちのわずかな部分に過ぎない。
エンジニアは特にこのコストに敏感だ。「効率が悪い作業」を嫌う職業病みたいなもので、カードを手で作るくらいなら自動化したい、とすぐ思う。でもその自動化のコードを書く前に力尽きる。
じゃあ、最初からそれが全部解決された状態を作ればいい。
用意されている環境
以下の機能がすべてCobo Memoに実装されている。
1. 暗記曲線に従った自動スケジューリング
エビングハウスの忘却曲線は有名だ。学習直後から急速に忘れ、時間が経つほど忘却が緩やかになる。
逆に言えば、「忘れそうなタイミングで復習する」のが最も効率的だ。
アプリを開くだけで「今日やるべきカード」が出てくる。自分でスケジュールを管理する必要はない。
アルゴリズムの実装詳細は前々回の記事に書いた。概要を下に示す。
カードの習熟状態は7段階で管理している:
| 状態 | 意味 | 次の復習まで |
|---|---|---|
learning |
学習中 | 翌日 |
relearning |
再学習中 | 2日後 |
young1 |
定着化(初期) | 3日後 |
young2 |
定着化(中期) | 7日後 |
young3 |
定着化(後期) | 14日後 |
youngmature |
ほぼ定着 | 30日後 |
mature |
完全定着 | Ease Factorで動的計算 |
Ankiの標準的な2〜3段階より細かく分けたのは「進んでいる感」を出すためだ。learning と mature の2段階だけだと、なかなか mature にならなくて挫折感が生まれやすい。
また、累積正解率80%以上のカードは、1回間違えても進捗が維持される。 「何十回も正解したカードを疲れている日に1回間違えたらゼロに戻る」という理不尽を避けている。これが地味に継続率に効く。
バックエンドはDynamoDB Streams → SQS → Lambda(Python)の非同期構成で動いており、アプリ側は書き込むだけでバックグラウンドで状態が更新される。
2. 同じ問題を何度でも回せる「練習モード」
復習日にかかわらず、同じカードを繰り返し練習したい場面がある。試験前夜、苦手な単元だけ集中してやりたいとき、など。
暗記学習モードをOFFにすると、習熟状態を変えずに練習だけができる。 統計(試行回数・正解数)は更新されるが、nextReviewDate や state は変わらない。
def compute_mastery_stats_only(old, attempts, correct, local_today):
"""練習モード:totalAttempt/totalCorrect/progressRateのみ更新"""
new_total = int(old.get('totalAttempt', 0)) + attempts
new_corr = int(old.get('totalCorrect', 0)) + correct
return {
'totalAttempt': new_total,
'totalCorrect': new_corr,
'progressRate': new_corr / new_total if new_total else 0.0,
'lastLearnedTime': local_today.isoformat(),
# 以下は変更しない
'nextReviewDate': old.get('nextReviewDate', local_today.isoformat()),
'state': old.get('state', 'learning'),
'daysElapsedSinceMature': int(old.get('daysElapsedSinceMature', 0)),
'easeFactor': float(old.get('easeFactor', 2.5)),
}
「前日に全部やって翌日の復習をスキップする」という抜け道を防ぎつつ、練習としての利用は自由にできる設計だ。
3. 一問一答 / 四択の切り替え
インプット直後は一問一答(フリー入力または答えを見るだけ)で流れを掴む。
定着フェーズでは四択にして「もっともらしいが違う選択肢から正答を選ぶ」訓練をする。
基本情報技術者試験や応用情報は選択問題が多い。一問一答で「答えは知っている」状態になっても、本番の選択肢の形式で出されると崩れることがある。四択で練習しておくと、選択肢を見た瞬間の判断精度が上がる。
四択の誤答生成は、プロンプトで「同カテゴリの類似概念を使う」と明示的に指示している:
prompt = f"""
## ルール
- 誤りの選択肢は、もっともらしいが明確に間違っているものにする
- 同じカテゴリの類似サービス・概念を使い、明確に間違っている選択肢を生成する
- 補足説明には、正解の根拠と誤りの選択肢がなぜ違うかを含める
"""
「TCPとは?」に対して誤答が「Pythonのライブラリ」では練習にならない。「UDP / HTTP / IP」のように、同じプロトコル層から選ばせることで、関連概念の整理にもつながる。
4. AIへの一言でカードを大量生成できる
「基本情報の資格勉強のカードを作って」 とテキストで投げるだけで、カードが自動生成される。
Lambda(Python)から Gemini API を呼び出して、構造化されたカードデータを生成している。
import json
import google.generativeai as genai
def generate_cards(text: str, num_cards: int = 10) -> list[dict]:
prompt = f"""
以下のテキストまたはリクエストから、学習用フラッシュカードを{num_cards}枚生成してください。
## 出力形式
JSON配列のみを出力してください。説明文やコードブロック記法は不要です。
[
{{
"question": "問題文",
"answer": "正解",
"supplement": "補足説明(なぜその答えになるかの解説)",
"select1": "誤りの選択肢1",
"select2": "誤りの選択肢2",
"select3": "誤りの選択肢3"
}}
]
## テキスト / リクエスト
{text}
"""
model = genai.GenerativeModel("gemini-2.0-flash-lite")
response = model.generate_content(prompt)
raw = response.text.strip()
if raw.startswith("```"):
raw = raw.split("\n", 1)[1].rsplit("```", 1)[0]
return json.loads(raw)
「基本情報技術者試験のデータベース分野のカードを10枚作って」と入力するだけで、問題・答え・補足・四択がセットで揃う。
参考書のページを撮影して投げ込む画像入力にも対応している(Geminiのマルチモーダル入力を活用)。
def generate_cards_from_image(image_bytes: bytes) -> list[dict]:
model = genai.GenerativeModel("gemini-2.0-flash-lite")
response = model.generate_content([
{
"mime_type": "image/jpeg",
"data": base64.b64encode(image_bytes).decode("utf-8")
},
"この画像の内容からフラッシュカードを生成してください。(出力形式は上記と同様)"
])
# ... パース処理
5. ライブラリから他のユーザーのカードをダウンロードできる
カードを1枚も作らずに始める方法がある。
ライブラリには、他のユーザーが公開したデッキが並んでいる。 基本情報技術者試験のデッキ、AWS SAA のデッキ、英単語のデッキ——ダウンロードして即復習を始められる。
技術的には、SharedSpace という共有機能の上に構築されている。ロールベースの権限管理(オーナー・編集者・閲覧者)を持ち、公開設定で生成されたリンクからダウンロード可能にしている。
Users → SharedSpace → RootStorage(デッキ) → Card
↑
role: owner / editor / viewer
visibility: public / private
「カードを作るのが面倒」という人は、まず誰かが作ったデッキで始めて、物足りなくなったら自分でカスタマイズするという流れが一番摩擦が少ない。
使い方のイメージ:基本情報を受ける場合
-
アプリを開いてAIに「基本情報技術者試験のアルゴリズム分野のカードを作って」と入力
→ 10〜20枚のカードが数秒で揃う -
ライブラリを検索して「基本情報」のデッキをダウンロード
→ 他のユーザーが整理したカードをそのまま使える -
毎日アプリを開くと「今日やるべきカード」が出てくる
→ 5〜10分の通勤時間だけでも回せる -
苦手な分野は練習モードで繰り返す
→ 習熟状態を崩さずに集中練習 -
試験前は四択モードで本番形式に慣れる
→ 選択肢の罠を見抜く訓練になる
「環境が整いすぎている」のに使わない理由はなんだろう
書き出してみると、こういう機能が全部揃っている:
- カードを自動生成できる(AIに一言でOK)
- 復習スケジュールを自動管理してくれる
- 同じ問題を何度でも練習できる
- 一問一答と四択を切り替えられる
- 他のユーザーのカードをそのままDLできる
ここまで環境が整っている状態で「カード作りが面倒」とか「何から始めればいいかわからない」という言い訳は難しい。
残る障壁は一つだ。「最初の1枚を引く」こと。
アプリを開いてAIに一言投げる。それだけで始まる。10枚カードが揃えば、今日の分は3〜4枚復習するだけでいい。5分あれば終わる。
その5分の積み重ねが、3ヶ月後に「受かった」になる。
まとめ
| 課題 | 解決策 |
|---|---|
| 何を覚えるかわからない | AIへの一言でカード生成(Gemini API) |
| カードを作るのが面倒 | テキスト・画像からの自動生成、ライブラリからのDL |
| 復習スケジュールが面倒 | 忘却曲線ベースのアルゴリズムが自動管理(Lambda×DynamoDB) |
| 同じ問題を繰り返したい | 練習モードで習熟状態に影響なく繰り返せる |
| 本番形式に慣れたい | 四択モードで「もっともらしい誤答」を選ぶ訓練 |
Cobo Memo(iOS / Android / Web 対応・無料で利用可能)
技術スタック: Flutter / AWS Amplify Gen2 / DynamoDB / Lambda (Python) / Google Gemini API
過去の関連記事: