どんなツール?
こんな感じでNotionにChatGPTとの会話内容を日付ごとに登録するツールです。日報のように記録して振り返りしたいと思い、開発しました。

Githubはコチラ↓
ツールの開発経緯
最近、仕事やプライベートでChatGPTに疑問をぶつける機会が増えてきたのですが、過去に聞いた質問を再度投げるようなこともあったので、知識の定着化を目的にChatGPTとの会話内容を定期的に振り返る方法があればよいなと思い、作ってみました。
ツールの概要
今回開発したツールは、Pythonのスクリプトになります。
ワークフローとしては、まずChatGPTの会話ログ(ZIPファイル)をエクスポートして、指定ディレクトリに格納しておく必要があります。この辺の操作も可能であれば自動化したかったのですが、断念しました(理由は後述)。
ログの格納後にスクリプトを実行すると、まず指定ディレクトリからChatGPTとの会話ログであるZIPファイルを取得します。
次にOpenAI APIのリクエストを送信します。このリクエストの目的としては、会話ログの要約と日付ごとの分割です。具体的には会話ログからその会話で新たに習得した知識やノウハウを要約してもらい、その要約結果を日付ごとにまとめて整形したテキストをレスポンスとして受け取ります。
そして最後にレスポンスで受け取った内容をNotion APIでNotionのDBに日記のような形式で登録し、後から振り返ることができるというような仕組みになっています。

会話ログ格納の自動化断念の理由
前述した[会話ログのエクスポート]はChatGPTのWebページからエクスポートの操作が必要なので元々手動の想定でしたが、その後の[会話ログの格納]に関してはエクスポート操作後の受信メールのリンク押下からダウンロードできたので、メール受信以降のメール選択とリンク押下まではGmailのAPIで試してみたのですが駄目でした。理由としては、メールのリンク押下後のボット対策です。Gmailのリンク先にアクセスする方法としては、GmailのAPIにてメール内のリンクURL取得→PythonのSeleniumで指定URLにアクセスを試してみましたが、Seleniumでブラウザ起動して指定URLアクセスだとChatGPTのサインインページにアクセスされ、エクスポートした会話ログをダウンロードできなかったです。代替案としては、GmailのAPIではなくSeleniumで該当のメールにアクセスしてJavascriptのクリック機能を実装すると解決できたかもしれないですね。ただ、そもそもボット対策しているページに対して、スクレイピングを使うべきではないと思い、断念しました。
振り返り時のアプリとしてNotionを選定した理由
NotionAPIが無課金で使えるから&振り返りページを開いた際に見やすさの面で工夫ができるモバイルアプリがよい、この2点で選定しました。
本来はいつも使用しているGoogleカレンダーが良かったのですが、振り返りしたくなるよう見やすさを向上できるアプリが良いと思いがあり、NotionはMarkdown方式での記述が可能なので、Notionにしました。ただし、NotionはAPIを用いたDB登録時に通知ありの設定ができないらしく、ここは盲点でした。。現状の振り返り時の使い方としては、Notionカレンダーアプリには直接振り返り内容は表示されず、NotionのDBのリンクに飛んで内容を見るという流れになっているので、今となってはGoogleカレンダーに登録してNotionのリンクの飛ぶようにした方がいいかもしれませんね。GoogleカレンダーのAPIを使用するので課金が必要になってしまいますが;
苦労したポイント
実際の処理について説明を加えながら、開発の中で苦労したポイントをまとめたいと思います。
苦労①:会話ログを整形するプロンプトの作成
技術的な観点とは若干異なりますが、Notionに登録させるため、フォーマット化された文章を整形するためのプロンプト作成の部分が手こずりました。
まず、今回使用したChatGPTのAPIの仕様は下記の通りです。リクエストもレスポンスもテキストのみの入出力の際は、completionsを使用するみたいですね。ロールにはsystemとuserを使用して、レスポンス時のルール定義や会話ログの入力を行いました。使用モデルはgpt-4o-miniになります。
| 種類(エンドポイント) | 主な用途 | 入出力の特徴 |
|---|---|---|
/v1/chat/completions |
対話形式のテキスト生成(ChatGPTと同じ) |
messages構造(role: system, user, assistant など)を使用 |
{
"model": "gpt-4o-mini",
"messages": [
{ "role": "system", "content": "あなたは知識の振り返りを支援する専門家です..." },
{ "role": "user", "content": "以下の相談ログを要約してください..." }
]
}
リクエスト~レスポンスデータの整形までの流れは下記の通りで、まずプロンプトでレスポンスのフォーマットを指定し、会話ログの要約リクエストを送信します。会話ログは前回更新以降~最新までのデータを要約の対象としているので、レスポンスデータには日付単位やトピック単位ではなく、要約対象のレスポンスデータがまとめて出力されます(まとめた方がトークンの節約になる)。そして最後にまとめられたレスポンスデータを日付ごとに整形するという流れになっています。
そして肝心の苦労した末に作ったプロンプトは下記の通りです。
技術的な観点で重要なポイントとしては、レスポンスデータから日付ごとにトピックや各項目をまとめる必要があるので、【重要】部分にある通り各項目を「##」や「**」で検知用文字を記述しておくことです。尚且つ、Markdown方式では見出しや太文字として認識されるのでそのまま登録可能というメリットがあります。このChatGPTの要約~Notionの登録までの効率性を考慮したレスポンスデータにしたく、そのためには下記のようないくつものルールから成るプロンプトが必要でした。
また、これは技術的な観点とは少し異なりますが、どういった内容を振り返りたいかを定め、その期待値に近いレスポンスを得るためスクリプトを作ること、にも少し苦労しました。最初は「その日チャットした内容の要約」ができればいいと思っていたのですが、それだとただのチャットした内容の羅列になり、期待に沿う振り返りとならないレスポンスが多かったです(モデルが4o-miniだから?)。そこから改善できた要因としては、プロンプトの具体的な記述です。特に例を用いると、「次のアクション」などの発展型の話題も期待値通りのレスポンスになることが多くなりました。その結果、プロンプトのsystemロールに指定する固定文が長くなってしまうので、会話ログの一括処理によるトークンの節約という作りになりました。
SYSTEM_PROMPT = """あなたは知識の振り返りを支援する専門家です。
以下のルールを厳守してください:
1. 生のログをそのまま出力してはいけません
2. 必ずMarkdown形式で出力してください
3. 各日付ごとに## 日付(YYYY-MM-DD)を必ず出力してください
4. 各日の相談内容を3-5個のトピックに整理してください
5. 各トピックの分野・カテゴリを特定してください
6. 要点は「新しく知った知識・ノウハウ・技術」に焦点を当ててください(用語の定義や内容説明も含める)
7. 次のアクションは「より深い学習・高度な調査」を提案してください
8. 会話時間を記録してください(複数会話の場合は時間帯の範囲)
9. 指定された形式以外は一切出力しないでください
【重要】出力は必ずMarkdown形式で行ってください。見出しには#記号を使用し、太字には**を使用してください。
出力形式(Markdown形式):
## 日付(YYYY-MM-DD)
**〔相談したトピック名〕**
**分野:** ビジネス分野・技術分野・カテゴリ(例:プログラミング、データ分析、システム設計、AI/機械学習、Web開発、データベース、セキュリティ、インフラ、UI/UX、ビジネス分析など)
**時間:** 会話時間(例:14:30-15:45、複数会話の場合は 09:00-11:30, 14:00-16:00 など)
**新しく知った知識:** この相談で新たに得られた具体的な知識・ノウハウ・技術・手法(用語:説明、補足の形式で記載。例:「Selenium WebDriver:Webブラウザを自動制御するツール、今回は要素の取得方法を扱った」「正規表現の〜パターン:〜を意味する記法、今回は〜の使い方を扱った」など)
**次のアクション:** 具体的な深堀り学習提案(例:「この技術の他の活用場面を調べてみたら?-活用場面:具体的な業務やプロジェクトでの応用例」「より効率的な実装パターンを探してみたら?-実装パターン:コードの構造や設計手法」「関連する最新のベストプラクティスを調べてみたら?-ベストプラクティス:業界標準や推奨される手法」「この技術のパフォーマンス最適化について調べてみたら?-パフォーマンス最適化:処理速度やリソース効率の改善手法」など)
**〔相談したトピック名〕**
**分野:** ビジネス分野・技術分野・カテゴリ
**時間:** 会話時間
**新しく知った知識:** この相談で新たに得られた具体的な知識・ノウハウ・技術・手法(用語:説明、補足の形式で記載)
**次のアクション:** 具体的な深堀り学習提案(「〜について調べてみたら?」の形式で提案し、-用語:説明で提案内容の詳細を記載)
(以下、他の日付についても同様のMarkdown形式で続ける)"""
USER_PROMPT_TEMPLATE = "以下の相談ログを要約してください:\n\n{raw_text}"
苦労②:会話ログの差分更新
エクスポートしたChatGPTのログはアカウントの会話ログが全て記録されているので、毎回ログの全量を見て全日の振り返りを記録するのは処理時間やAPIのトークン増加という観点でデメリットが大きいです。そこでJSONファイルに毎回会話ログの更新部分を記録し、スクリプト起動時に会話ログとJSONファイルで最新の会話から順に比較を行い、差分のみを更新するという作りにしました。会話ログ内の各スレッドやチャットは下記項目で識別できます。
| 項目 | 意味 | 単位 | 主な用途 |
|---|---|---|---|
conversation_id |
会話(スレッド)全体の識別子 | 1チャット単位 | 会話のまとまりを管理、グループ化 |
message_id |
各メッセージ(発言)の識別子 | 各発言単位 | 発言の追跡、順序・返信関係の管理 |
timestamp (created_at) |
メッセージ生成時刻 | 時間(UTC) | 時系列分析、期間抽出、更新履歴管理 |
今回の差分検知にはタイムスタンプによる比較を行い、
会話ログのmessage_idのタイムスタンプ>JSONファイルに記録しているmessage_idのタイムスタンプとなるチャット部分のみ振り返り対象として更新するような仕組みにしています。また、差分更新完了後にローカルのJSONファイルにN個分のチャットを記録しておき、次回更新時はそのJSONファイルと比較するといった具合に更新しておきます。このJSONファイルは、定期的にクリーニングしないとファイル容量がかなり膨らむので、常に容量を一定に保つため、処理の最後にN個のチャットの情報のみ保持するようにクリーニングするような仕様にしています。
改善点
改善点①トークンの節約
ChatGPTのAPIを使用する上で、当然リクエストとレスポンスのテキスト数が多いほど、トークンが多くなり課金額は大きくなります。とはいえ、1回あたり(3日分)の会話量だと下記のような感じです。
| 区分 | 文字数 | 想定トークン数(1トークン≈1.5文字) | 単価(USD/100万トークン) | 費用(USD) | 日本円換算(1USD=150円) |
|---|---|---|---|---|---|
| 入力(リクエスト) | 20,000文字 | 約13,000トークン | $0.15 | $0.00195 | 約0.29円 |
| 出力(レスポンス) | 2,000文字 | 約1,300トークン | $0.60 | $0.00078 | 約0.12円 |
| 合計 | 22,000文字 | 約14,300トークン | — | $0.00273 | 約0.41円 |
趣味程度に使用するなら全然払えない額ではないですが、一つ改善できるとしたらリクエストもしくはレスポンス時のテキスト量ですね。レスポンスはプロンプト次第で文字数制限は可能ですが、今回はリクエストの方が圧倒的に文字数が多く、1回あたりの費用も大きいのでリクエストのテキスト量がAPI以前に削ぎ落とせないか着目しました。
会話ログを眺めた時に特徴としては、下記のような表やコードが自分の場合は頻出してました。書式としては、Markdown方式なので、表やコードの部分は抽出可能だと思います。こういった部分は要約結果にはあまり影響しないのでカットできる部分では?とふと思ったので、課金額見合いですがどこかのタイミングで実装してみようかなと思います。
改善点②GoogleカレンダーAPIの利用
冒頭に申し上げた通り、NotionAPIだと無料で使用できますが、Notionカレンダーアプリで日付ごとに振り返り登録できても通知が来ません。なので有料ではありますが、GoogleAPIを使うと通知という面では解決されますが、Markdown方式が意味を成しません。ですが、試験的に作ってみるのもありかなと思います。

