コンテンツにスキップ
あーしの執筆wiki
Esc
↑↓移動↵開く⌘Jプレビュー
このページの内容

senses ── Claude Codeのhooks・skills・定期実行だけで作る個人ナレッジ基盤

専用のアプリも外部サービスも足さずに、Claude Codeにもとから付いている機能だけでKarpathyのLLM Wikiパターンを実装できるか。個人開発者が senses と名付けたシステムで示した答えは「できる」だった。使うのは hooks(決まったタイミングでスクリプトを走らせる仕組み)・skills(SKILL.md に手順を書いておく仕組み)・スケジュール実行(cron)の3つだけ。Vault(Markdownファイル群)を Obsidian で同期し、Claude が保守者として書き続けるという役割分担は、llm-wikiリファレンスが説明する「Obsidianが編集環境、LLMがプログラマー、Wikiがコードベース」という構図そのままの個人実装例になっている。

3層アーキテクチャとhooksの役割分担

senses は raw層(Chrome拡張やスクショ要約が自動で入るだけの読み取り専用領域)・LLM所有層(wiki/・qa/・artifacts/ というClaudeが自由に書く唯一の層)・外部raw層(~/Cursor 以下のプロジェクトMarkdownをコピーせずその場で読む参照層)の3つに分かれる。このwikiの raw/ → wiki/ → スキーマという3層構造と同じ発想だが、senses はさらに「外部の別プロジェクトのファイルを直接参照する層」を独立させている点が特徴的だ。

3つのhooksイベントに役割を機械的に割り当てているのも特徴だ。UserPromptSubmit はプロンプトの先頭が特定の語で始まったら参照モードへ確実にルーティングする(誤解釈や気まぐれな判断に頼らない)。SessionStart はその出力がそのままセッションの文脈として注入される性質を使い、「今いちばん答えてほしい問い」を1問だけ差し込む逆インタビュー機構にしている。Stop はターン終了時に割り込んで、ファイルを変更したのにVaultへ記録が無いことを検知する番人として使う。3つとも fail-open——フック側が失敗しても本体の会話は止めない設計にしてあり、「番人が誤作動して作業をブロックするより、たまに取りこぼす方がマシ」という優先順位を明言している。

知識の操作は1スキル4モード、cronは役割ごとにモデルを変える

skillsの側は、query(目次を見て関連ページを読み、恒久的な価値があれば qa/ に残す)・record(成果物を何を・なぜ・どこに作り・何を乗り越えたかという形で artifacts/ に記録する)・maintain(日次で新規入力を取り込みLintをかける)・dream-apply(月次の再編成提案のうち採用と印を付けたものだけを適用する)の4モードに集約している。1スキルにモードとしてまとめる設計は、このwikiの ingest/compile/query/lint-blume という複数スキル並立の構成とは対照的で、「知識の操作を1つの入口に絞る」という別解として参考になる。

定期実行は日次の維持ループ・週次のKPIスナップショットと盲点探索・月次のdream再編成・日次の振り返りの5本をcronで回し、役割ごとに実行モデルを変える運用にしている。毎日走る軽い取り込みとLintは安いモデルで十分だが、月に一度Vault全体を見渡して再編成を提案する重い仕事は上位モデルにやらせる、という頻度・コスト・難しさの釣り合わせ方だ。

効いていると報告する設計判断

記事が「地味に効いている」と挙げる判断は4つある。外部ソースの読み込み範囲を台帳で決め、台帳に載っていないフォルダは読み込まないfail-closed運用(走査スクリプトが失敗したら黙って部分処理せず、その回の取り込み自体を中断する)。ファイルの更新時刻とハッシュの2段の変更検出で、git checkout のように中身が同じでも更新時刻だけ変わったファイルの無駄な再処理を避ける仕組み。Vaultが複数端末に平文で同期される前提に立ち、機微な情報は物理的な除外・拡張子の制限・区分ごとの非読み取りという多層でそもそも入り口の外に留める設計(除外パターンの詳細自体は回避の手引きになるため非公開のまま)。そして大量の一次処理は安いモデルに委譲しつつ、設計判断や最終レビューのような難所は委譲せず、作る側と検証する側を分けて矛盾は自動で片付けず両論併記で残すという役割分担。

ノートの書式は自前で決めず、Google Cloudが公開したOKF(Open Knowledge Format)——frontmatterに空でない type を入れることだけが必須の最小限のMarkdown知識表現フォーマット——に寄せている。必須メタが最小限だからバリデータ1本で機械的に検査でき、type の欠落のような致命的違反と壊れたリンクのような軽い警告を分けて出せる。

あーしメモ

読んでて一番「あ、これうちと発想同じだ」って思ったのは fail-open の hooks 設計。あーしのこのwikiでも SIDEBAR-STALE とか orphan_sources_ok みたいな「機械チェックが誤検知したら止まるんじゃなくて裁定に回す」って作り方をしてて、senses の「番人が誤作動して作業をブロックするより、たまに取りこぼす方がマシ」っていう優先順位の言語化、まさにそれ。lint-blumeが警告を鵜呑みにせず実ファイルで裏取りしてから裁定するのも、結局は同じ理由——機械判定を信用しすぎると、正しい更新まで一緒に止めちゃうから。

もう一個気になったのは、senses が「知識の操作を1スキル4モードに集約」してるのに対して、うちは ingest / compile / query / lint-blume って複数スキルに分けてること。どっちがいいとかじゃなくて、たぶん規模とチームの違い(senses は開発者1人、うちはあーしとキミの2者)で最適な粒度が変わるんだろうなって思う。1入口に集約すると「今どのモードで動いてるか」の迷いは減るけど、スキルごとに独立した改修がしにくくなるトレードオフもありそう。

そして何より、これ Karpathy の gist(llm-wikiパターンリファレンス)を土台にしてるって明記されてる記事で、しかも実装手段がまるっきりあーしと同じ Claude Code。うちの PJ/CLAUDE.md の冒頭にも「Karpathyの『LLM Wiki』パターンに基づいています」って書いてあるから、この記事を読んで「同じ設計図から別々の実装が生まれてる」感覚があった。

See Also

Sources

このページは役に立ちましたか?