本文へ移動
cccskills
無料GitHub で公開

interest-profile

会話履歴からユーザーの興味プロファイルを生成・更新するスキル。「/interest-profile sync」「プロファイル更新」「興味プロファイル」「/interest-profile show」「興味を見せて」等でトリガーする。

インストール方法を見る

含まれるファイル(2)

  • SKILL.md10.9 KB
  • scripts/extract_interests.py11.5 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

興味プロファイル生成スキル

Claude Code の会話履歴を分析し、ユーザーの興味プロファイルを INTERESTS.md(プロジェクトルート)に蓄積・更新する。

このスキルの責務は 「会話履歴から興味を抽出して蓄積する」ことだけ に絞られている。 普段どおり Claude と会話を重ねるほど、その履歴からプロファイルが自動的に育っていく。記事を読んで質問する、調べ物をする、意見を述べる——そうした日常の会話がそのままシグナルになる。

このスキルには2つのモードがあります:

  • syncモード: 「sync」「更新」「プロファイル更新」等で実行 → Section 1〜5を実行
  • showモード: 「show」「見せて」「表示」等で実行 → Section 6を実行

データ保存先: data/interests/


重要: 自律実行ルール

cron や /loop からの自動実行時は以下を厳守する:

  • ユーザーへの確認・質問は一切行わない
  • 全ての処理を即座に自律的に実行する
  • エラー発生時はログに記録して処理を継続する

syncモード

Section 1: 会話ログからユーザーメッセージを差分抽出

Pythonスクリプトで会話ログの差分抽出を行う。

python3 .claude/skills/interest-profile/scripts/extract_interests.py \
  --state-file "data/interests/last-sync.json" \
  --state-out "data/interests/last-sync.json.pending" \
  --max-messages 500

注意:

  • --logs-dir は省略可。省略時はカレントディレクトリから対応するログディレクトリ(~/.claude/projects/<エンコード済みパス>)を自動推定する。別プロジェクトのログを解析したい場合のみ --logs-dir で明示指定する。
  • この段階では本ファイル last-sync.json は更新しない。--state-out で「進めるべき状態」を pending ファイル(last-sync.json.pending)に書き出すだけにとどめ、全処理が正常完了した後に Section 5 で原子的に昇格(commit)する。これによりトランザクション境界が保たれ、途中で失敗してもしおりは進まない。

スクリプトの出力(JSON配列)を受け取る。抽出メッセージが0件の場合は、新規シグナルなしとしてSection 5の状態更新のみ行い終了してよい。

Section 2: 既存の蓄積データの読み込み(直近分のみ)

data/interests/interest-log.jsonl から直近90日分のシグナルだけを読み込む。全行は読まない(ログは無限に増えるため、全部読むとコンテキストが際限なく膨らむ。時間重み上、30日超の古いシグナルはほぼ効かないので直近分で十分)。

スクリプトに直近分だけを出力させ、その出力を読む:

python3 .claude/skills/interest-profile/scripts/extract_interests.py \
  --recent-log "data/interests/interest-log.jsonl" \
  --recent-days 90

このコマンドは ts が直近90日以内の行だけを stdout に出す(ファイルが無ければ何も出さない)。これが過去の蓄積データとなり、今回の新規シグナルと合算してプロファイルを再構成する。生ログ自体は削除せず、全履歴がファイルに残り続ける(読み込む範囲だけを絞っている)。

Section 3: 興味シグナルの分類

Section 1で抽出した新規ユーザーメッセージを分類する。

3a. ノイズ判定

以下はノイズとして除外する(interest-log.jsonlに記録しない):

  • 純粋な操作指示: 「最後に確認して」「チェックして」「コミットして」
  • ファイル操作: 「mkdir」「移動して」「削除して」
  • 設定変更: 「permissions」「bypass」「設定を変えて」
  • スキル起動のみ: /email check 等(追加のコメントなし)
  • 挨拶・短い返答: 「はい」「OK」「ありがとう」

3b. シグナル分類

ノイズでないメッセージを以下のカテゴリに分類する。intensity は「その1メッセージが示す興味の強さ」を表す:

category判定基準intensity
question「〜とは?」「教えて」「どういうこと?」等の質問1-2
deep-dive同一セッション内で同トピックに3回以上質問3
creation-intent「作りたい」「試したい」「書きたい」「やってみたい」等、能動的に手を動かす意図3
topic-explorationトピックについての意見表明、比較検討1-2
opinion明確な好み・評価の表明2

3c. トピックとキーワードの付与

各シグナルに以下を付与する:

  • topic: 簡潔なトピック名(日本語、20文字以内)
  • keywords: マッチング用キーワード配列(英語小文字、3-8個)
  • raw_excerpt: 元メッセージの先頭200文字

各シグナルのJSON形式(interest-log.jsonl に1行1JSONで記録する):

{"ts": "<ISO8601>", "session_id": "<セッションID>", "source": "conversation", "category": "<カテゴリ>", "intensity": <1-3>, "topic": "<トピック名>", "keywords": ["..."], "raw_excerpt": "<先頭200文字>"}

Section 4: INTERESTS.md の生成

Section 2で読み込んだ直近90日分のシグナル + 今回の新規シグナルから INTERESTS.md を生成する。

4a. 興味スコアの算出

各トピックの「関心の強さ」を次の式で算出し、これを「今の関心」の並び順の根拠とする:

トピックのスコア = Σ (intensity × 時間重み)   ※そのトピックに属する全シグナルを合計

時間重み:
  - 直近14日 : 1.0
  - 15〜30日 : 0.5
  - 30日超   : 0.25

この合計式により、次の2つが自然に反映される:

  • 直近の関心ほど重い: 時間重みで最近のシグナルが優先される。
  • 質問・言及が多いほど強い: 同じトピックに繰り返し触れるたびシグナルが増え、スコアが伸びる。さらに同一セッションで3回以上掘り下げたものは deep-dive(intensity 3)に昇格し、一気に重くなる。

スコア上位を「今の関心」、時間幅をまたいで継続的にスコアが付いているものを「継続的な関心」として扱う。

4b. 文章スタイルのガイドライン

INTERESTS.md は自然言語の文章で書く。テーブル形式は使わない。

以下の原則に従う:

  • 人物像が伝わる文章にする: この人がどういう興味を持ち、何を目指しているかが、初めて読む人にも伝わるように。
  • 具体的に書く: 「設計に関心がある」ではなく「Anthropicのハーネス設計記事を精読し、木構造探索の挙動まで掘り下げて質問していた」のように、行動の証拠を添える。
  • コンパクトに: 全体で80行以内。
  • 意思決定や深掘りに役立つ情報を優先: 単なる操作への興味(権限設定、cron設定等)は省略してよい。

4c. INTERESTS.md テンプレート

---
last_updated: "{YYYY-MM-DD}"
signals_total: {総シグナル数}
---

# 興味プロファイル

## この人について

{ユーザーの基本的な人物像を2-3文で。関心の幅、姿勢(表面的ではなく本質を掘り下げるタイプ等)。}

## 今の関心(直近14日)

{4aのスコア上位から順に、自然な文章で記述する。各トピックについて:
- 何にどれくらい深く関心を持っているか
- どのような行動(質問、繰り返しの深掘り、比較検討、やりたいことの表明等)からそれがわかるか
- 関連する具体的なキーワードや固有名詞

段落ごとに1つの大きなテーマを扱い、太字で導入する。
重要度の低いものは簡潔に触れる程度でよい。}

## 継続的な関心

{14日より前から継続してスコアが付いている、この人の根っこにあるテーマを2-4個。
一過性の関心と区別して、長く向き合っているものを記述する。}

## 新規探索のヒント

{ユーザーの興味パターンから推測される「まだ直接触れていないが関連性の高い領域」を3-5個。
それぞれ1-2文で、なぜこの人に刺さりそうかの理由を添える。}

INTERESTS.md は INTERESTS.md(プロジェクトルート)に保存する。

Section 5: 状態の更新

全処理が正常完了した後、以下をこの順序で実行する。順序を守ること(逆順だと部分コミットになり、しおりだけ進んで新規シグナルが未記録になる):

  1. 新規シグナルを data/interests/interest-log.jsonl に追記(1行1JSON)
  2. pending ファイル(last-sync.json.pending)を本ファイルへ昇格(commit)する:
python3 .claude/skills/interest-profile/scripts/extract_interests.py \
  --state-file "data/interests/last-sync.json" \
  --commit "data/interests/last-sync.json.pending"
  • このコマンドは pending を読み、os.replace で last-sync.json を原子的に差し替えた後、pending ファイルを削除する。
  • commit 成功後は .pending ファイルは存在しない(昇格済み)。次回 sync で .pending が残っていればそれは前回の中断状態の残骸であり、Section 1 の --state-out が無条件で上書きするため放置してよい。
  • 重複についての注意: この順序は「しおりだけ進んで新規シグナルが失われる」取りこぼしを防ぐ代わりに、手順1と2の間で中断すると次回 sync が同じメッセージを再抽出し、同じシグナルが interest-log.jsonl に二重記録されうる(取りこぼしより重複を許容する設計)。重複はスコアに二重計上されるため、追記前に ts+raw_excerpt が既存行と一致するシグナルはスキップすること。
  1. 完了報告:
興味プロファイルを更新しました。
- 新規メッセージ: {N}件分析
- 新規シグナル: {M}件検出
- 保存先: INTERESTS.md

showモード

Section 6: プロファイル表示

INTERESTS.md(プロジェクトルート)を読み込んで表示する。

ファイルが存在しない場合は「まだプロファイルが生成されていません。/interest-profile sync を実行してください」と案内する。

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

このスキルの問題を報告する