🌊

ChatGPT+LlamaIndexでVoicyの放送を要約してみる

2023/06/26に公開

こんにちは。Voicyエンジニアのゆうじです。

Voicyでは毎日多くの方が音声で放送していますが、聴きたいコンテンツが多すぎて時間が足りないなんてことありませんか。

そこで今何かと話題のChatGPTを使って、放送の内容を短いテキストに要約して、どんな内容の話をしているかを簡単にわかるようにしてみたいと思います。また簡単にChatGPTを直接呼び出すために、今回はLlamaIndexを使用してみます。

今回作成したものこちらのGoogleColabで確認できます。

LlamaIndexとは

LlamaIndexとは、外部のさまざまなデータとLLM(大規模言語モデル。今回はChatGPT)を簡単に繋ぐことためのライブラリです。
2023年6月時点の最新は0.6.32になります。
https://gpt-index.readthedocs.io/en/latest/

音声をテキストに変換

今回使用する放送は弊社社長緒方のこちらの放送を、社長に無断で試してみようと思います。

要約する前に、WisperAPIを使用して音声をテキストへ書き起こしました。今回は要約の部分について話したいので、WisperAPIの使い方についてはこちらの記事を参考にしてみてください。

出来上がったテキストの全文はこちらになります。

ボイシー社長の頭の中、皆さんお元気? まさかのね、昨日のアボカドの放送がですね、めちゃくちゃ人気で反響があってですね、 なんだ、俺のリスナーさんは求めてるのそこか?っていう感じなんですよね。 いいねの数とかもめっちゃ多いし、コメントなんて今までダントツやし、みたいな、 どこだどこだ、カスクレでたやつって思いながらもですね、 まあみんないろんなアボカドの作り方が載ってては、なんかね、 これがボイシーのコミュニティの作り方かと思うと、それも面白いなと思います。 ぜひね、コメントを持った方はどんどん入力してください。 で、ボイシーの方のチャンネルはですね、僕の頭の中を普段考えたことだったりとかをお届けしていこうと思っています。 パーソナリティの人たちには、配信のコツをお話しすることもありますし、 多くの方が役に立つような話もぜひしていきたいなと思っています。 で、そうですね、今日はですね、ちょっと全然違う話をしたいなというふうに思っていて、 人生の中で生き方として、こんな生き方すごくいいんだよ、 もしくはこういうのダメなんだよとか、 そういう話もね、ちょっと自分の中での気づいた範囲でしていきたいなと思っています。 その中で、あなたは効果的効率的に生きてますか?っていうことですね。 この効果的効率的に生きることの差っていうのはめちゃくちゃ出てくるんだよっていう話をちょっとしてみたいなというふうに思います。 はい、で、ここでね、皆さんにお願いがあります。 ボイシーの尾形のLINEの公式アカウントが出ました。 こちらですね、ぜひ聞いている方はですね、登録してください。 概要欄に載せています。 ここにはですね、LINEに返していただけたらね、返したメッセージは僕の方で実は読めてます。 で、メッセージがあんまりイケてないなとか、意外と面白いなとか、感想とかもLINEで返しちゃってください。 でね、文章の改善とかをしていきたいと思います。 まだちょっとした業者感があるかもしれないので、そこもね、うまくやってきたので、皆様のご返事お待ちしております。 でね、えっと、そうですね。 今日の効果的効率的にいった話っていうのはめちゃくちゃ役に立つと思います。 僕がこれを気づけるようになったのはだいぶ後でした。 だからこそ、ぜひ皆さんにも知っておいてもらえたらと思うし、いつからでも遅くないんじゃないかなと思います。 仕事がうまく覚えられない、なかなかうまくいかない、人間関係がうまくいかないとかね、 自分は物覚えが下手なんじゃないか、時間がいつの間にか過ぎていく、そんなこと山ほどあるわけです。 でも、よりよく仕事できる人がさっさと終わって、次の仕事もできて評価されて、どんどんスパイラルに回っていくのにとかね、 いい人はうまくスパイラルで回るのに、悪い自分は全然ダメだと思っていることないですか。 もしくは、自分は好きなことはどんどんできるのに、全然他のことはできないなとか、 ゲームのプレイだけどんどんうまくなっていくのに、リアルの社会では私は全然成長せんぞって言ってる方に思っている方、いませんかね。 当たり前です。なぜなら、あなたは効果的に効率的に動いてないからですよね。 どういうことかって言ったらね、例えば、Aっていう仕事を振られました。 その仕事を、よし頑張るぞってやります。 とりあえずやって、ある程度やりました。できたって言って部長に出しに行きます。 ここもちょっとこうだよね。ここだけこういう風に直してくれる? わかりました。直しました。 じゃあテストオン。ありがとう。これでいいや。 はい、ありがとうございます。よし、終了。 今日もオフ。全部忘れた。仕事もやったし。お金欲しいな。やった分だけ欲しいなって。 いう人がほとんどだと思うんですよね。 でもこれ、もし勉強とかスポーツだったらどうですか。 よし、この数学の問題解いてみようって。 とりあえず、ある程度解きました。先生どうですか。 いや、こことかもうちょっとこういう風に直したら答えまで言ってるんだけど惜しかったね。 こことかこうだからねって赤ペン書いてるのを見て、 あっ、わかりました。それで直しちゃうかったんですね。先生ありがとうございます。 じゃあこれでということで、よかった。終わったって言った人、次数学の問題その問題解けますかね。 すいません。バットにうまく当たりません。ちょっと見ててください。 なんか変に当たるね。もうちょっとさ、腰を振ってこういう風にやって。 こうやったら飛ぶんだよって。先生見せてくれてありがとうございます。監督。 わかりました。じゃあ次回からそうするようにします。 この人バット振れますかね。振れないですよね。 じゃあどうやったらスポーツってうまくいくのかって考えて、 あなたがトレーナーだったら何をするか。 何も考えず闇雲に100回素振りしてる高校生を見て、 いいんじゃないのよ。頑張ってるなって言いますかね。 その高校生が最も進めるなら、まずいいバットの振り方っていうことを 見本をいろいろ見て、こんな感じなんだって知りながら、 自分も100回振ってみるものの、それを自分で動画に撮ってみて、 こうやったらできるんだっていうのを自分と見本との差を見てきたりとかして、 それでだんだんうまくなって、やったものを他の人から見てもらって復習していって、 うまく打てたなと思ったら、そのうまく打てたのをもう一回やってみるとかしてみるわけですよね。 数学の問題も一回先生に見せて、こうやって採点を返ってきたら、 それをもう一回回答を見ずに解いてみて、何回も何回も解いたら初めて その数学の問題解けるようになるわけじゃないですか。 なのに仕事になった途端に、もう提出して、全部完璧にできたわけじゃないのに提出したら もう終わりで復習しないし、それから先輩に半分直してもらったやつなのに、 自分でもう一回これゼロからやったらちゃんとできるかなっていう確認とかをしてないから、 より良かったものが血肉に全くなってないわけですよね。 それからうまくやった人の仕事のモノマネをしてみたこともかなり少ないと思います。 よりうまくやった人の本とか効率とかをググって調べたこともあまりないんじゃないか。 自分の見本を取得したことがない。 ほとんど仕事で参考にする良い見本をほとんど取得せずに、自分なりに我流にやって 最終上司にちょっと修正されたものをそのまま提出して、後はすべて水に流すってやってたら そりゃスキルも上がらないし、自分の血肉にならないですよね。 一方で、これをちゃんと同じようにスポーツのようにやってる人たちは 圧倒的なスピードで成長していくわけです。 良い見本を手に入れること、自分のフィードバックをちゃんと得ていくこととか そういうものを取得するってのがめちゃめちゃ大事なわけですよ。 できるところまでもう一回やるっていうことを染み込ましても 数学の問題も次の日に解いてみたらまた解けないじゃん。 そこから何日か解けるようになるまでもう一回やって 一週間後とかにもう一回やってみようとするとまたできなかったりするよね。 それを入れていって頭に染み込ましていくわけです。 実際に僕も公認会見書の試験の勉強してるときは 忘却曲線とかを勉強して、まず100%にしても知識は次の日には50%に落ちてる。 そして一週間経つとまた50%に落ちるっていう風になってるっていうのを使って これをより多くするには一日目に100覚える。 二日目にまた50のものを100まで戻す。 そして一週間後にまたそこからそこの時は全く50にまでいかないんだよね。 ちょっと60くらいになったけど、それをまた100に戻す。 一ヶ月後にもう一回100に戻すっていうことをやると染み込んでいくんだよとかやってみたら 本当にちゃんと頭に入ってくるんですよね。 例えばスポーツをやるにも何の筋トレもせず柔軟運動もせずに いきなりふーんって振ったら腰痛いってなるわけですよね。 何の仕事の練習もせずいきなりめっちゃ難しいことやってて 徹夜でふーんってやったら、それはもういろんなところ壊れますわね。 っていうことを他のモノマネができるのに 仕事になった瞬間に全然変わっちゃう人がたくさんいるわけですよね。 仕事になった瞬間に最低限やってパイって出したら逃げたいみたいなね。 とにかくやりたくない子ってなってるわけです。 これはもしお子さんがいる方とかもそうですけど もしお子さんがいてですね、勉強ちゃんと伸びてほしいなと思ってのに 宿題、やったもん、やったもん、もういいでしょ、やったんだから明日休んだから 出していったら先生が出してきて 4割ぐらいしか点取れてなくて他の人がミスってると ちゃんと答え合わせしてやりなさい、もうやったんだからいいでしょ 次またその問題出た時にまたやるしって言ってたら その人には期待できんよね。 なのでそこの成長曲線が圧倒的に低いわけですわ。 ほとんどの人が成長曲線低いままでそのまま進んでいくんですよね。 次自分がもっと高い仕事を得たいと思えば そんなものは当然できるようにして次やらないといけない。 次もずっと同じ仕事でいいんだったらスキルセットを伸ばさずにそのままいたらいいんですが 一定年齢がたってくるとスキルセットを上げてない高年者っていうのは 会社からしたら結構つらい。 若い子にもっとチャンスをあげたいしってなるわけですよね。 私その仕事は若い人に次は渡したいから早めに成長しても次の仕事を受けてくれってなってるのに 君の成長が足りないと後ろ使えてるんだけどっていうことになってきます。 そして大合敵していくってなると自分より年上の人を追い抜いていくっていう若手って精神的にめちゃくちゃ大変なわけですよね。 その人に対して敬語にするのか、ちゃんと指示できるのかとかになってくるので 一定年齢になってちゃんと成長してないっていうことは 結構周りからしたらつらい立場になってしまうこともあるわけです。 自分はどうやったら効果的に効率的に成長するのか。 それは予習をしていくことなのか、何回も繰り返しできるところまでやることなのか。 それとも筋トレやストレッチのようにベーシックな能力をつけていくのか。 そうやって自分の業種の中ではどうやったら最高速度で成長するのか。 そこを最大チューニングするっていうことをとにかくやることをお勧めしたいなと思って今日はこの話をしてみました。 参考になったら嬉しいです。感想もください。 それではどの声とつながりますか。

事前準備

  1. LlamaIndexのライブラリをインストール
!pip install llama-index
  1. OpenAPIのAPIキーを環境変数に設定
    APIキーはOpenAPIに自分のアカウントでログインしたらこちらから作成することができます。
import os
os.environ["OPENAI_API_KEY"] = "自分のAPIキーを指定"

インデックス作成

テキストをそのままChatGTPに投げるのではなく、一旦ベクトル化します。

# 要約したいテキスト
text = "text = "ボイシー社長の頭の中、皆さんお元気? ・・・"
# テキストを読み込むためのReaderを取得
documents = StringIterableReader().load_data(texts=[text])
# VectorStoreでテキストをベクトル化
index = GPTVectorStoreIndex.from_documents(documents)

元のテキストが長いと、このベクトル化に時間がかかることがあるので、ローカルに保存して使い回すこともできます。もちろん元のテキストが変更になった場合は作り直す必要があるので注意してください。

保存する処理も追加するとこんな感じです。

storage_path = "./storage"

# インデックスを取得
try:
    # 既存のインデックスを読み込み
    storage_context = StorageContext.from_defaults(persist_dir=storage_path)
    index = load_index_from_storage(storage_context)
except Exception:
    # インデックスが取得できなければ新たに作成して保存
    # テキストを読み込むためのReaderを取得
    documents = StringIterableReader().load_data(texts=[text])
    # VectorStoreでテキストをベクトル化
    index = GPTVectorStoreIndex.from_documents(documents)
    # ベクトル化したデータをローカルに保存
    index.storage_context.persist(persist_dir=storage_path)

テキストを要約

インデックスが作成できたらいよいよChatGPTに要約するように問い合わせを行います。

query = "テキストの内容を300文字以内で要約してください"

# 問い合わせ実行
query_engine = index.as_query_engine()
response = query_engine.query(query)
print(response.response)

実行結果はこちら

ボイシー社長は、アボカドの放送が大変な人気を集めたことを知り、自身のコミュニティを作るために、効果的で効率的な生き方を皆さんに伝えることを目指しています。そのため、LINEの公式アカウントを作成し、皆さんからのメッセージを受け取ることをお願いしています。皆さんからのメッセージを受け取ることで、ボイシー社長はより良いコミュニティを作ることができると考えています。

んー微妙ですねw 実際の放送を聞いてもらうとわかりますが、アボガドとかLINEとかは最初の雑談で話していることで、この放送のメインコンテンツではないのですが、、

問い合わせクエリーをカスタマイズ

要約の内容をより良くするために、要約を指示している問い合わせクエリーを工夫してみましょう。

放送のタイトルが内容を表していることが大半なので、試しにタイトルの情報を加えてみます。

問い合わせクエリー

テキストの内容を300文字以内で要約してください。このタイトルは「効果的・効率的に成長すること意識してますか?」です

要約結果

本文では、効果的・効率的に成長することを意識しているかどうかについて話しています。若い人が仕事をうまくこなし、次の仕事を受けられるようになるためには、効果的・効率的に動くことが重要であると述べています。また、仕事をうまくこなすためには、予習をしたり、何度も繰り返し行うことなどが重要であると述べています。最後に、自分の業種の中で最高速度で成長するためには、自分の能力を最大限にチューニングすることが重要であると結論付けています。

おぉ、雑談部分がなくなって、先ほどよりもかなり良くなりましたね。ざっくり「要約して」といった指示ではなく、ある程度方向性を示してあげることが大切なようです。

聞いたことある方も多いと思いますが。ChatGPTの使い方でよく言われているのが、先に役割を指定してあげるのがいいと言われているので、さらにそれも追加してみましょう。

問い合わせクエリー

あなたは文章を要約するプロフェッショナルです。テキストの内容を300文字以内で要約してください。このタイトルは「効果的・効率的に成長すること意識してますか?」です

要約結果

仕事を効果的・効率的に行うことは、評価を受けたり、スパイラルで成長したりするために重要です。しかし、自分が物覚えが下手であることや、時間が過ぎていくことなど、様々な問題があります。そのため、自分がどうやって効果的・効率的に成長するかを考える必要があります。予習をしたり、何度も繰り返し行ったり、基本的な能力を身につけたりすることで、自分の業種で最高速度で成長することができます。

余計な部分が削ぎ落とされて、少しスマートな感じになりましたね。この辺はいろいろ工夫することでもっとよくすることはできそうです。

これってChatGPT使ってるの?

ここまでのコードを見ると、使用しているのはLlamaIndexのライブラリばかりで、ChatGPT(正確にはOpenAI API)を本当に使ってるのか?という疑問が出てきます。

そこで、試しに事前準備で環境変数に指定したOPENAI_API_KEYを削除して実行してみると

Did not find openai_api_key, please add an environment variable `OPENAI_API_KEY` which contains it, or pass  `openai_api_key` as a named parameter. (type=value_error)

というエラーが出たので、OpenAIを使ってそう感はあります。詳細は割愛しますが、このエラーが出たGPTVectorStoreIndex.from_documentsの部分からLlamIndexのコードを追っていくと、最終的にこちらに辿り着くのですが、引数に何も指定していない場合はLangChainのOpenAIライブラリでtext-davinci-003をLLMとして指定しているのがわかります。

from langchain import BaseCache, Cohere, LLMChain, OpenAI
・・・
def __init__(
    self,
    llm: Optional[BaseLanguageModel] = None,
    retry_on_throttling: bool = True,
    cache: Optional[BaseCache] = None,
    callback_manager: Optional[CallbackManager] = None,
) -> None:
    """Initialize params."""
    self._llm = llm or OpenAI(
        temperature=0, model_name="text-davinci-003", max_tokens=-1
    )

最後に

AIはまだ触り始めたばかりでわからないこともたくさんありますが、それ以上に可能性が多く、サービスをさらに成長させていく力があるなと感じます。サービスを安定して運用していくことも大事ですが、こういった技術革新のタイミングではその波に乗って非連続な成長に繋げることもエンジニアの大事な役目だと思うので、引き続きキャッチアップを続けていこうと思います。

そんなVoicyでスキルもサービスも一緒に伸ばしていきたいと感じた方は、ぜひこちらも合わせてご覧いただけると幸いです。
https://www.wantedly.com/companies/voicy

Voicyテックブログ

Discussion