🦜

LangChainでアカウントの一貫した人格の投稿を無限生成してみた

2024/03/23に公開

1. 動機

最近とあるキャラクターの X アカウントを運用しています。キャラクターアカウントは、ユーモアあふれる投稿や独自の世界観、ストーリー性が重要で、それによって根強いファンを獲得したりフォロワーを集めることができますが、一貫した人格を持ったキャラクターアカウントの投稿作成をゼロから考えて継続的に作成するのは容易ではなく、投稿文章の作成にそれなりに労力がかかっていました。この課題を解決するため、生成 AI を活用することで時間とコストを削減しようと思ったのが今回の動機です。

2. 使用技術

LangChain、Pinecone、TypeScript、Google API を使用しました。

LangChain は、LLM に基づいてアプリケーションを構築するためのオープンソースのライブラリです。今回はモデルは Claude 3 Sonnet を使用しました。Pinecone は、ベクトル DB で、類似性に基づくデータの検索と参照が可能です。普段から慣れている TypeScript をそのまま使用して、Google API は最終的にスプシに投稿をリストで出力させるために使用しました。

3. 課題と解決した方法

課題: 人格を持ったキャラクターの一貫性のある投稿内容の生成

キャラクターアカウントの投稿内容を自動生成しようとした際に課題だったのが、キャラクターを「意図した人格」で一貫して反映させることでした。キャラクターの性格、口調、生活スタイルなど、一貫した人格要素を投稿に反映させる必要があり、これらの要素が既存の投稿・世界観と一致していないと、ファンは違和感を感じてしまいます。

解決した方法:

過去の既存投稿データを使用

まず、すでに投稿されている過去の投稿を一定量 CSV に吐き出し、Pinecone に保存しました。これにより、新たに生成する投稿が過去の投稿と一貫性を持つように参照として利用することができました。プロンプトだけをゴリゴリ書いても、データソースがゼロの状態で投稿を生成するのでは期待する内容に近づけることは非常に困難なので、独自のコンテキストを持ったデータソースの活用は必須でした。

Pinecone のメタデータを工夫

Pinecone を利用して、投稿内容のメタデータに「投稿日時」「曜日」「投稿のテーマ」を持たせて類似検索をすることで、生成される投稿内容を期待する内容にある程度近づけることができました。既存の投稿内容を 7〜10 個くらいのテーマに分類して、全ての投稿についてそのテーマのいずれかを紐づかせて Pinecone に保存しました。いずれのメタデータもシステムプロンプトで使用するのですが、特に「投稿のテーマ」をメタデータとして使用することで、類似検索から生成の過程において威力を発揮し大きな的外れな文章が生成されることがなくなりました。

システムプロンプトの改善

プロンプトで、生活スタイルにおける定数の部分は固定するようにしました。これにより、キャラクターの人格をより正確に反映させることができました。具体的には、対象のキャラクターの生活スタイル(何曜日に何をすることが多くて、何時にどこで何をすることが多いか)をプロンプトに定義すること、そして、その生活スタイルの中で、どの曜日にはどの「投稿テーマ」を生成させるのか、をシステムプロンプトで指定することで期待する内容の生成結果がより精度高く出るようになりました。あとはキャラクターの人格を表現するための情報として、口癖のフレーズは固定したり、句読点や絵文字の使用頻度と種類についても指定することで不自然さがほぼなくなりました。

例えばドラ ○ もんに登場する ○ び太を例にすると以下のような指定をしました。ここでは、「学校でのできごと」「夕方の公園でのできごと」などの投稿テーマが、既存の投稿のメタデータとして Pinecone にすでに定義されている前提です。

- 生活スタイル:
    - 平日: 学校に行く
    - 土日: 家で過ごすことが多い
    - 夕方: よく公園で遊ぶ
- 投稿テーマ:
    - 月曜日: 学校でのできごと
    - 火曜日: 夕方の公園でのできごと
    - 水曜日: 帰宅後の夜の家でのできごと
    - 木曜日: 学校でのできごと
    - 金曜日: 帰宅後の夜の家でのできごと
    - 土曜日: 家でドラえもんとのできごと
    - 日曜日: スネ夫、ジャイアン、しずかちゃんのいずれかとのできごと
- 口癖:
    - 「どらえもおおおーん!」
    - 「~だしてくれえ」
- 文体に関する条件:
    - 文章に必ず「!」「〜」「。。。」「😇」「🥳」「🙂」のいずれかが入り、これ以外の絵文字は使用しないこと
    - 文章は最大でも 3 文までにすること

実際はこの 4,5 倍ほどの情報量を定義したのですが、このようにキャラクターの性格や生活パターンを細かく指定することで、そのキャラクターらしい自然な投稿を生成できるようになりました。

実際に生成されたが不採用だった投稿を NG 例としてプロンプトに追加

上記の方法で生成していく中で、それでも 10 個中 3,4 個くらいは何か絶妙に違和感がある投稿が生成されることがありました。そこで、その生成された文章自体をプロンプトに「NG 例」としての参考情報としてプロンプトに追加しました。実際に生成されたけど微妙に惜しい投稿を 10 個ほど定義してその NG 理由を記載することで、その NG 理由に該当する投稿は生成されなくなり、違和感のない投稿が生成される割合が高くなりました。

結論

キャラクターアカウントの投稿内容を自動生成する際には、過去の投稿の活用、Pinecone のメタデータの工夫、そのメタデータと関連を持たせたプロンプトの定義をすることで、キャラクターの人格や生活スタイルに一貫性を保ちながら、期待するの内容のコンテンツを生成することが可能になりました。また、実際に生成された NG 例をプロンプトに定義、OK 例を Pinecone に保存することで継続的に改善することもできると感じました。

4. まとめと今後の展望

既存投稿データの活用、Pinecone のメタデータ工夫、プロンプトの工夫で、10 個中 8 個くらいは違和感なくそのまま採用できる投稿文章として生成できるようになりました。ただ、この運用をより簡単に、そして本来の目的であるアカウントのエンゲージメントを高める内容を生成するために行えることとして、以下の点が考えられます。

  • 投稿のエンゲージメントを踏まえた生成処理の改善: 投稿に対するユーザーのリアクション(いいね数、リツイート数など)をメタデータとして保存し、それらの情報も活用して生成を行うこと
  • フィードバックシステムの構築: 生成内容を実際に投稿した後にそれらの投稿をよりシームレスに Pinecone に保存して以降の類似検索に使用できる仕組みを作ること

既存の仕様で運用しつつ、このあたりの実装も必要に応じてやってみたいと思います。

Discussion