okaryo.log

Scrapboxに毎日書いている開発日誌をOpenAI APIを使って週報としてまとめる | okaryo.log

Scrapboxに毎日書いている開発日誌をOpenAI APIを使って週報としてまとめる

    #Scrapbox#OpenAI

この記事にはアフィリエイトリンクが含まれています。

はじめに

『達人プログラマー』という本の中で開発日誌の作成が勧められており、それを数年前に読んで以来Scrapboxに開発日誌を書くようになった。

かなり開発日誌のページ数が溜まってきており、もっと振り返りしやすくするために流行りのGPTを使って週報としてまとめてみることにした。

開発日誌のフォーマット

フォーマットは日々模索中で、たまに変えたりしているが最近は以下のようになっている。

開発日誌 yyyy/mm/dd

* 今日の体調
* 今日の作業
* 仕事のメモ
* プライベートのメモ
* 世界のメモ
  * 天気
  * 社会の出来事

#開発日誌 #yyyy/mm/dd

開発以外にもプライベートなことや社会の出来事もメモしており、その日のことを思い出しやすいようにしている。

Scrapboxの性質的に日付ごとにページを作成するのはアンチパターン感はあるが、個人のプロジェクトなので目を瞑ってほしい。

週報作成用のスクリプト

以下が週報作成用のユーザースクリプト。

// code:script.js
// 注意: 週報作成後にtitlesを空にする
const weeklyReportTitle = encodeURIComponent("週報 2023/07/03~2023/07/09");
const titles = `
開発日誌 2023/7/3
開発日誌 2023/7/4
開発日誌 2023/7/5
開発日誌 2023/7/6
開発日誌 2023/7/7
`
  .split("\n")
  .filter((title) => title !== "")
  .map((title) => encodeURIComponent(title));

if (titles.length > 0) {
  console.log("================Start weekly report generation=================");
  const urls = titles.map(
    (title) => `https://scrapbox.io/api/pages/okaryo/${title}/text`,
  );
  const responses = await Promise.all(urls.map((url) => fetch(url)));
  const pages = await Promise.all(responses.map((response) => response.text()));
  const pageBoundary = "----boundary----";
  const prompt = `
  後述する日誌ページの内容を、以下の項目に合わせてまとめてください。
  
  * 1週間の体調
  * 1週間の作業一覧
  * 仕事のまとめ
  * プライベートのまとめ
  * その他1週間で考えたこと・やったことまとめ
  * 社会の出来事まとめ
  
  また、各項目は以下のフォーマット例に従ってください。日付ごとの項目を省略しないでください。省略すると世界が破滅します。
  
  項目見出し
  * まとめ: [1週間の内容をまとめる]
  * 2023/01/01: [日付ごとの内容をまとめる]
  * 2023/01/02: [日付ごとの内容をまとめる]
  
  さらに、ページの最後に以下のフォーマット例でタグを追加してください。
  
  #週報 #開発日誌 #2023/1/1 #2023/1/2
  
  以下が各ページの内容です。各ページは${pageBoundary}によって区切られています。
  
  ${pages.join(pageBoundary)}`;

  const openAIKey = "ひみつ";
  const bodyData = {
    model: "gpt-4",
    messages: [{ role: "user", content: prompt }],
  };
  const response = await fetch("https://api.openai.com/v1/chat/completions", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      Authorization: `Bearer ${openAIKey}`,
    },
    body: JSON.stringify(bodyData),
  });

  const result = await response.json();
  const body = encodeURIComponent(result.choices[0].message.content);
  console.log(`https://scrapbox.io/okaryo/${weeklyReportTitle}?body=${body}`);
  console.log("================Finish weekly report generation=================");
}

週報作成用のWebサイトを作ろうとしたが、ScrapboxのAPIにアクセスするにあたってCORSに引っかかるのでユーザースクリプトから実行するようにした。

また、ページの作成はhppts://scrapbox.io/プロジェクト名/タイトル?body=本文にアクセスすることで実現できる。しかし、ブラウザを経由しないとページが作成できないのでGPTで本文が作成された後にURLをコンソールに出力し、それを自分でクリックして作成している。作成するのは週一なので妥協した。

上記の処理やプロンプトの内容について改善点や一家言ある方がいらっしゃればぜひコメントで教えていただけると嬉しい。

出力結果

上記のスクリプトを読みんで実行してコンソールに出力されたURLをクリックすると、以下のページが作成された。

Output

一旦これで運用してみて、適宜プロンプトを調整して項目やまとめ方を模索していこうと思う。

感じた課題・反省点

出力結果やスクリプト作成を経て感じた課題や反省点は以下。

  • 開発日誌は毎日ちゃんと書かないとだめで、週報でまとめた際にすぐ手抜きがバレる
  • まとめるページ数やページの内容量が多くなってくるとOpenAI APIの最大トークン制限にひっかりそう

特にトークン制限は切実な問題だ。現在使っているモデルのgpt-4で最大8,192トークン。本当は32,768トークンまで使用できるgpt-4-32kモデルを使用したいが、試してみるとエラーが出て使えなかった。近いうちに使えるようになってくれるとありがたい。

おわり

自分のScrapboxのプロジェクトはプライベートなため出力された週報については完全に自分用となっているが、そのうち公開用に改修したものをブログの方で公開しようと思っている。

週報作成プロセスやプロンプトの内容、週報の項目について一家言ある方はぜひフィードバックいただけると嬉しい。


関連記事
最新記事
プロモーション

This site uses Google Analytics.