Skip to content
cccskills
FreePublished on GitHub

interest-profile

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

The English summary is being prepared. Showing the original description.

See how to install

Files included (2)

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

SKILL.md (original)

Review the instructions the agent will receive before you install.

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

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 を実行してください」と案内する。

Reviews

No reviews yet. Tell others what you thought.

Comments

No login needed. Share how it worked for you, ask a question, or note where it did not run.

No comments yet. Be the first to write one.

Comments are published right away. Do not include personal information such as email addresses or phone numbers. Up to 2 URLs.

0 / 1,000 characters

This form is protected by reCAPTCHA, and the Google Privacy Policy and Terms of Service apply.

Report a problem with this skill