RAGるリフレクションツール

[NSSOL Advent Calendar 2024](https://qiita.com/advent-calendar/2024/nssol)の11日目の記事です。
私は、とある部門で技術系業務と部門HRBPの二足の草鞋を履いており、本記事も技術×HRネタを書いてみました。
[610さんの記事](https://note.com/610_mto/n/n349994db2ae7)に背中を押され（蹴られ？）、エントリーしてみました。技術プロフェッショナルな記事は他の方々に任せ、私はゆるっとした内容を担当させていただこうと思います。

最初は「ラブトランジットから学ぶチームビルディング」について熱く書こうと思ったのですが、Qiitaの趣旨的に（だいぶ）違うなと考え直し、最近勉強がてら自身のリフレクションツール（振り返りツール）を初心者RAGで作ってみたので、そちらの内容にしました。
「RAGって概念はわかるんだけど、実装の手触り感がないんだよなぁ…」という方は私以外にもきっといると信じ、そういう方の参考になればうれしいです。

https://qiita.com/advent-calendar/2024/nssol

## 自己紹介
最初に少しだけ自己紹介を。2008年に入社しDWH構築案件などのエンジニアキャリアを歩み、2022年からグループリーダーとして組織マネジメントも担ってきました。
そんな中、当社も実施していたエンゲージメントサーベイと対話会で「うーん、逆にエンゲージメント下がってない？」と思うことがありつつ、「でも、どうしたらよい？」に好奇心がくすぐられ、働きがいや組織開発について学び始めました（今も絶賛勉強中）。
そんな経緯もあり、今は技術系業務半分、部門HRBP半分として充実した日々を送っています。

## 作ったもの
Notionに書いた日記をベクトルデータベースに格納し、RAGでリフレクションツールを構築したお話です。

今回のリフレクションツールを作る前と後のがどんな感じだったかのイメージ↓
![運用イメージ画像.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3950580/4aaf1e08-bbec-fb38-7842-d92b0c03f279.png)


## 実装
全体イメージはこんな感じ↓
![アーキテクチャ図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3950580/b0b46eff-92f8-5416-736f-e2de64246dae.png)

参考書籍（というかこちらをほぼ写経してます）
『LangChainとLangGraphによるRAG・AIエージェント［実践］入門』
https://amzn.asia/d/balQuin

### 実装コード
私と同じRAG初心者が「RAGって簡単！？」と思ってもらえるよう、「①Chunk分割＆ベクトル化」と「②RAG」の部分のみを抜粋しています。（詳しく知りたい方は是非上記参考書籍を）

①「Chunk分割＆ベクトル化」
```python
# 変数「documents」にPDFから読み込んだテキストが格納されている

# NotionPDFが入った変数を決めた長さに分割(Chunk分割)
text_splitter = CharacterTextSplitter(separator="\n",chunk_size=1000, chunk_overlap=125)
docs = text_splitter.split_documents(documents)

# embeddingモデルをセット
embeddings = OpenAIEmbeddings(model="text-embedding-3-small")

# chunk化されたテキストをベクトル化しベクトルデータベース(Chroma)に格納
# ベクトルデータベースに格納することで「問い」に近い内容の日記を探すことができる
db = Chroma.from_documents(docs,embeddings)

# ベクトルデータベース(Chroma)をRetrieverとしてセット
retriver = db.as_retriever(search_type="similarity", search_kwargs={"k": 10})
```

②「RAG」
```python
# RAGでプロンプトを発行しやすくするためにテンプレートを作成
# ベクトルデータベースから検索した内容はcontextに、問いはquestionにセットされて
# 生成AIに投げられる
prompt = ChatPromptTemplate.from_template('''
以下の文脈だけを踏まえて質問に回答してください。

文脈:"""
文章：
{context}
"""
質問:{question}
'''
)

# OpenAIのモデルセット
model = ChatOpenAI(model="gpt-4o-mini",temperature=0)

# Chainをセット（パイプで繋ぐとその流れに沿って処理をしてくれる。便利。）
chain = (
  {"context":retriever,"question":RunnablePassthrough(),}
  | prompt
  | model
  | StrOutputParser()
)

# 問いをセット
query = "2024年12月に関心を持って取り組んでいたテーマは？"

# Chainを実行
chain.invoke(query)
```

各コードの意味は、さきほど紹介した[こちらの書籍](https://amzn.asia/d/h694xuR)に丁寧に書かれておりそちらに譲りますが、基本的なRAGがこの程度のコードで実装できることが私としては驚きでした。

ただ、稼働させていただいたコードが12月上旬からエラー(proxiesエラー？)を吐くようになり、エラーを解消するスキルと元気が足りず、足元はNotebookLMで代替運用してます（というより運用だけならこちらの方がおそらく便利）。
生成AI関連はコードの陳腐化速度がとても速いなと改めて痛感（本が出た瞬間にやらないと初心者は詰む…）。


## 日記とリフレクション

ここからは話が変わって、皆さん、リフレクション（振り返り）はどれぐらいされていますか？
振り返りの重要性は、[NSSOL AdventCalendar2024の6日目「初めてアジャイルをやってみた」](https://qiita.com/t00723/items/95c3ea0780daa1279764)でも語られていたり、[NSSOL AdventCalendar2024の10日目「POをスウォーミングでやってみた」](https://qiita.com/dodai10s/items/7bc7226ecd0840c8dc12)で語られている”高いモチベーションを持つ”ことにも振り返りは大事な要素と思っています。一方、「振り返るタイミングがわからない」「何を振り返ったらいいかわからない」、そんな声も時々耳にします。

私は、社会人になってから日記をつける習慣がつき、その中で自然と振り返りをしてきましたが、同じやり方をしていると飽きてしまうため、書籍等を参考にやり方を変えてきました。以降では、今参考にしている書籍をベースに私が実施している方法を紹介しようと思います。

### 日記
日記は[最高の未来に変える　振り返りノート習慣](https://amzn.asia/d/fRofhgF)を参考にして、毎日、
> 出来事
意味づけ

を３つずつNotionに書いています。

例えば、こんな感じのことを。（自分の日記を公開する恥じらいに耐えながら載せています）
>出来事：映画を一人で鑑賞するという時間の過ごし方
意味づけ：本を読む、と似ているけど、映画を見る時間が一見無駄に思えるけど、実は人生の充実において大事なノイズではないか。でもその時間を使っている自分にはっきりと自信が持てるわけではない。

何を書いたら正解ということはなく、なるべく自分の思考性や浮かんできた感情を書くようにしています。（情報漏洩に繋がるような情報は書かないように注意）

### リフレクション（振り返り）
下記のような問いをRAGに投げています。
> 日記からわかる著者の強みを３つにまとめてください
日記からわかる著者の思考・行動パターンを３つにまとめてください
日記から著者が関心を示していたことを３つにまとめてください
日記の著者は成長のためにはどのような思考の変化、行動の変化を起こせたらよいですか？

問いに対する生成AIの出力は、例えば、強みへの回答であれば、

>行動力 : 著者は、AWSのアップデート情報共有 や、dbtトライ など、新しい技術や知識を積極的に学び、業務に活かそうとする行動力を持っています。また、越境学習活動 や社外イベントへの参加 など、自己成長のために自ら行動を起こす積極性も持ち合わせています

（え、ありがとう…　嬉しいんだけど…）
生成AIとはいえ、自分の行動を踏まえたフィードバックをもらえるのは結構嬉しいですし、自分を客観視するヒントにもなると感じています。

　
また、成長のための思考/行動の変化に対しては、

>1. 「Why」を深掘りし、行動のモチベーションを持続させる
■著者は、新しい技術や知識を学ぶことに対しては高いモチベーションを示していますが、「なぜそれを学びたいのか」「どのように活かしたいのか」という「Why」の部分が明確でない場合があるように見受けられます。
■「Why」が曖昧なまま行動を続けていると、途中で目的を見失ったり、モチベーションが低下したりする可能性があります。
■改善策:
  □新しい技術や知識を学ぶ際には、その目的や目標を明確に言語化する
  □目標達成によって、自分や周囲にどのような影響を与えられるのかを具体的にイメージする
  □「Why」を定期的に振り返り、行動のモチベーションを維持する

（あ、はい、頑張ります・・・）
Gartnerさんも2025年に向けて獲得すべきマインドセットの１つとして「事例とやり方(How)の模倣ではなくWHYと結果にこだわる」を挙げられていましたので、「WHY」をキーワードに頑張ります。

まだ運用し始めて間もないですが、リフレクションの質が高まりそうな可能性を感じており、運用の簡素化や問いの工夫を引き続き試してみようと思います。


## 終わりに
最後までお読みいただきありがとうございます。
生成AIがパーソナルコーチになる日は近いと感じつつ、自分の思考や価値観は言語化しない限り、生成AIも理解（？）できないので、日々アウトプットしていくことが大事になりそうと感じています。
明日は、今年3回目の登場の610さんがアオアシについて語ってくれるようで楽しみです！