Slide 1

Slide 1 text

LangGraphとFlaskを用いた 社内資料検索ボットの実装 ①AIエージェント構築編 2024/11/30 機械学習の社会実装勉強会 第41回 熊懐 葵

Slide 2

Slide 2 text

目次 • 背景とモチベーション • 社内資料検索ボット Sofiaとは • AIエージェントとは • LangGraphとは • Sofiaの実装(エージェント部分) • 材料を揃える • 繋ぎ合わせる • 構築確認 1

Slide 3

Slide 3 text

プロジェクト・業務データ 背景とモチベーション 社内では、複数のソフトを連携させてプロジェクトを推進している Slack Jira Confluence Github 連携・通知 タスク管理 業務資料 開発 業務ノウハウを活かして業務効率化をしたい 2

Slide 4

Slide 4 text

社内資料検索ボット Sofia Sofia…Slack上で質問すると、JiraやConfluenceの情報を元に回答してくれる チャットボット Slack @Sofia <質問> 回答 + 参考URL 3

Slide 5

Slide 5 text

社内資料検索ボット Sofia Sofia…Slack上で質問すると、JiraやConfluenceの情報を元に回答してくれる チャットボット Confluence 社内情報にすぐ アクセスできる 4

Slide 6

Slide 6 text

社内資料検索ボット Sofia アプリケーション全体 Slack App Jira Confluence Cloud Run LangGraphで AIエージェントを構築 5

Slide 7

Slide 7 text

社内資料検索ボット Sofia の実装 やること • LangGraphを用いたAIエージェントの構築 • Flaskを用いたアプリケーション全体の構築 本発表の目的 SofiaのAIエージェント構築の説明を通して LangGraphを使ったAIエージェントの構築の仕方をわかりやすくまとめる 6

Slide 8

Slide 8 text

AIエージェント(マルチエージェント)とは 従来の生成AI 指示 回答 AIエージェント 指示 不正確・一貫しない回答 • 長い複雑な指示 • 専門性の高い質問 複数のモデルで構成された、複雑なタスクを正確に実行できるシステム 回答 Aして BorCをして Dする Aする Bする Cする Dする 正確で一貫した回答 • 複雑な指示を整理 • 専門で役割分担 7

Slide 9

Slide 9 text

LangGraph(v0.2.28)とは AIエージェント構築のためのフレームワーク • 複数の処理単位(モデル)や処理の遷移を整理しながら 構築できる Node Edge 入力 出力 • 入力~出力までずっと同じデータ構造を保持し、各 Nodeで更新していく State Graph • Node, Edge, State を合わせてAIエージェント Graph 8

Slide 10

Slide 10 text

SofiaのGraph 動作フロー 情報の取得先を選択(Jira or Confluence) Jira or Confluenceから関連情報を取得 関連度の低い情報を削除 質問の意図を読み取り、質問を修正する 回答を生成する 開始 終了 情報の再評価か生成か 再評価 生成 情報が残っているか No Yes 情報に基づくか No Yes 質問に答えているか Yes No • 質問: ~して • 取得先: • 回答: • 資料: • 質問: ~して • 取得先: Confl. • 回答: ~です • 資料: [URL] 9

Slide 11

Slide 11 text

SofiaのGraph 動作フロー 情報の取得先を選択(Jira or Confluence) Jira or Confluenceから関連情報を取得 関連度の低い情報を削除 質問の意図を読み取り、質問を修正する 回答を生成する 開始 終了 情報の再評価か生成か 再評価 生成 情報が残っているか No Yes 情報に基づくか No Yes 質問に答えているか Yes No • 質問: ~して • 取得先: • 回答: • 資料: • 質問: ~して • 取得先: Confl. • 回答: ~です • 資料: [URL] Node Edge (Conditional edge) State Graph 10

Slide 12

Slide 12 text

SofiaのGraph 実装のイメージ(graph.py) __start__ decide_datasource retrieve grade_documents transform_query generate __end__ grade_documents_ or_generate decide_to_generate grade_generation_v_documents_and_question • question: ~して • datasource: • generation: • documents: • question: ~して • datasource : Confl. • generation: ~です • documents: [URL] class GraphState(… def decide_datasource(… def grade_...question(… def create_graph(… 11

Slide 13

Slide 13 text

SofiaのGraph 実装ステップ 材料を揃える Stateを定義 Nodeを定義 Edgeを定義 繋ぎ合わせる Graphを定義 Nodeを追加 Edgeを追加 構築確認 Graphをコン パイルする 12

Slide 14

Slide 14 text

SofiaのGraph実装 材料を揃える > Stateを定義 State…Graphの状態を表すデータ構造 TypedDictを使って型付き辞書を定義する • 質問: ~して • 取得先: Confl. • 回答: ~です • 資料: [URL] GraphStateクラス 13

Slide 15

Slide 15 text

SofiaのGraph実装 材料を揃える > Nodeを定義 全部で5つのNodeを定義する __start__ __end__ grade_documents_ or_generate decide_to_generate grade_generation_v_documents_and_question 事前準備: chainの材料 • prompt • model • BaseModel or StrOutputParser decide_datasource retrieve grade_documents transform_query generate Nodeを定義する • chain(or retriever)を定義 • Stateから使用するデータを取得 • chainをinvoke • Stateのデータを更新 14

Slide 16

Slide 16 text

SofiaのGraph実装 材料を揃える > Nodeを定義 事前準備① prompt … 4つ( 以外) • system prompt…データをどう更新して欲しいか • human prompt…使用するStateのデータ system prompt の例 decide_datasource の場合: ※ あなたはユーザーの質問をConfluenceまたはJiraに振り分けるエキスパートです。Confluenceにはドキュメント があり、Jiraにはチケットがあります。質問が明示的にJiraやチケットを指している場合のみJiraを選択してください。 retrieve 15

Slide 17

Slide 17 text

SofiaのGraph実装 材料を揃える > Nodeを定義 事前準備① prompt … 4つ( 以外) • system prompt…データをどう更新して欲しいか • human prompt…更新したいStateのデータ retrieve __start__ __end__ decide_datasource retrieve grade_documents transform_query generate system prompt(ざっくり) あなたは、ユーザーの質問をConfluence またはJiraに振り分けるエキスパートです あなたは、質問と取得文書の 関連性を評価する採点者です あなたは、質問をより良い バージョンに変換する 質問リライターです あなたは、質問応答タスクのアシ スタントです。 以下の質問に回答して…。 あなたはX + Yして 16

Slide 18

Slide 18 text

SofiaのGraph実装 材料を揃える > Nodeを定義 事前準備② model …chat(ChatOpenAI)とretrievers 外部で定義し、引数として設定している(運用面を考慮) graph.py(Graph構築側) ※main.py(アプリ構築側) 各retrieverの構築はここでは割愛 17

Slide 19

Slide 19 text

SofiaのGraph実装 材料を揃える > Nodeを定義 事前準備② model …chatとretrievers __start__ __end__ decide_datasource retrieve grade_documents transform_query generate model(ざっくり) chat chat chat chat retrievers (confluence_retriever か jira_retrievers 18

Slide 20

Slide 20 text

SofiaのGraph実装 材料を揃える > Nodeを定義 事前準備③ BaseModel or StrOutputParser …chainの出力制御をする • BaseModel…pydanticのクラス。型ヒントを設定して、データバリデーション ができる。 • StrOutputParser…LangChainのクラス。modelの出力を文字列でそのまま返す。 BaseModelの例 StrOutputParserの例 型ヒント: str, 型詳細: 抽出資料が質問に関連しているか (yes / no) ※ 特に事前準備なし 19

Slide 21

Slide 21 text

SofiaのGraph実装 材料を揃える > Nodeを定義 事前準備③ BaseModel or StrOutputParser …chainの出力制御をする • BaseModel…pydanticのクラス。型ヒントを設定して、データバリデーション ができる。 • StrOutputParser…LangChainのクラス。modelの出力を文字列でそのまま返す。 __start__ __end__ decide_datasource retrieve grade_documents transform_query generate BaseModel or StrOutputParser (ざっくり) BaseModel Literal[“confluence”, “jira”], jiraチケット関連の時だけjiraを選ぶ BaseModel str, 抽出資料が質問に関連 しているか。yes か no StrOutputParser StrOutputParser 20

Slide 22

Slide 22 text

SofiaのGraph実装 材料を揃える > Nodeを定義 全部で5つのNodeを定義する __start__ __end__ grade_documents_ or_generate decide_to_generate grade_generation_v_documents_and_question 事前準備: chainの材料 • prompt • model • BaseModel or StrOutputParser decide_datasource retrieve grade_documents transform_query generate Nodeを定義する • chain(or retriever)を定義 • Stateから使用するデータを取得 • chainをinvoke • Stateのデータを更新 21

Slide 23

Slide 23 text

SofiaのGraph実装 材料を揃える > Nodeを定義 decide_datasource を定義 1. chainを定義 2. Stateから使用するデータを取得 3. chainをinvoke 4. Stateのデータを更新 chat + BaseModel + .with_structured_outputで出力制 御されたmodelを作る chain = prompt | model State • question: 使用 • datasource: 更新 • generation: • documents: 22 “Jira”か”Confluence”と出力する

Slide 24

Slide 24 text

SofiaのGraph実装 材料を揃える > Nodeを定義 retrieve を定義 1. (retrieverを外で定義済) 2. Stateから使用するデータを取得 3. invoke 4. Stateのデータを更新 ※main.py(アプリ構築側) State • question: 使用 • datasource: 使用 • generation: • documents: 更新 23 取得した資料データを出力する

Slide 25

Slide 25 text

SofiaのGraph実装 材料を揃える > Nodeを定義 grade_documentsを定義 1. chainを定義 2. Stateから使用するデータを取得 3. chainをinvoke 4. Stateのデータを更新 chat + BaseModel + .with_structured_outputで出力制 御されたmodelを作る State • question: 使用 • datasource: • generation: • documents: 使用/更新 24 ループ内で資料ごとに”yes”か”no”を出力する yesならdocumentsに残す

Slide 26

Slide 26 text

SofiaのGraph実装 材料を揃える > Nodeを定義 transform_queryを定義 1. chainを定義 2. Stateから使用するデータを取得 3. chainをinvoke 4. Stateのデータを更新 State • question: 使用/更新 • datasource: • generation: • documents: chain = prompt | model | Parser 25 より良い質問に修正し、出力する

Slide 27

Slide 27 text

SofiaのGraph実装 材料を揃える > Nodeを定義 generateを定義 1. chainを定義 2. Stateから使用するデータを取得 3. chainをinvoke 4. Stateのデータを更新 State • question: 使用 • datasource: 使用 • generation: 更新 • documents: 使用 chain = prompt | model | Parser documentsの情報を整理 26

Slide 28

Slide 28 text

SofiaのGraph実装 材料を揃える > Nodeを定義 generateを定義 1. chainを定義 2. Stateから使用するデータを取得 3. chainをinvoke 4. Stateのデータを更新 State • question: 使用 • datasource: 使用 • generation: 更新 • documents: 使用 Nodeの定義完了 27 回答を生成

Slide 29

Slide 29 text

SofiaのGraph実装 材料を揃える > Edgeを定義 事前準備: chainの材料(※) • prompt • model • BaseModel Edgeを定義する • chainを定義(※) • Stateからチェックするデータを取得 • chainをinvoke(※) • chainの結果に応じて文字列を出力 _start_ decide_datasource retrieve grade_documents transform_query generate _end_ grade_documents_ or_generate decide_to_generate grade_generation_v_documents_and_question 全部で3つのEdge(Conditional Edge)を定義する ※ Stateのデータ チェックにchainを 使う ※ Stateのデータ チェックにchainを 使う NodeはStateのデータを出力 28

Slide 30

Slide 30 text

SofiaのGraph実装 材料を揃える > Edgeを定義 事前準備: chain3つ分を揃える(割愛) • prompt…3つ • model…全てchat • BaseModel…3つ _start_ decide_datasource retrieve grade_documents transform_query generate _end_ grade_documents_ or_generate decide_to_generate grade_generation_v_documents_and_question documentsが回答に十分かチェックするchain 回答が事実に基づくかチェックするchain 回答が質問に答えているかチェックするchain 29

Slide 31

Slide 31 text

SofiaのGraph実装 材料を揃える > Edgeを定義 grade_documents _or_generateを定義 1. chainを定義 2. Stateからチェックするデータを取得 3. chainをinvoke 4. 文字列を出力 State • question: 使用 • datasource: • generation: • documents: 使用 chat + BaseModel + .with_structured_outputで出力制 御されたmodelを作る chain = prompt | model 30

Slide 32

Slide 32 text

SofiaのGraph実装 材料を揃える > Edgeを定義 grade_documents _or_generateを定義 1. chainを定義 2. Stateからチェックするデータを取得 3. chainをinvoke 4. 文字列を出力 State • question: 使用 • datasource: • generation: • documents: 使用 chainの結果(yesかno)に応じて 出力する文字列を変える chainの判断材料: • question • documentの数 • documentのmetadata 31

Slide 33

Slide 33 text

SofiaのGraph実装 材料を揃える > Edgeを定義 decide_to_generateを定義 1. chainを定義 2. Stateからチェックするデータを取得 3. chainをinvoke 4. 文字列を出力 State • question: • datasource: • generation: • documents: 使用 documentが残ってないなら質問を修正 documentが残っているなら回答生成 32

Slide 34

Slide 34 text

SofiaのGraph実装 材料を揃える > Edgeを定義 grade_generation_v_documents_and_questionを定義 1. chainを定義 2. Stateからチェックするデータを取得 3. chainをinvoke 4. 文字列を出力 State • question: 使用 • datasource: • generation: 使用 • documents: 使用 chat + BaseModel + .with_structured_outputで 出力制御されたmodelを作る 33 回答が事実に基づくかチェックするchain 回答が質問に答えているかチェックするchain

Slide 35

Slide 35 text

SofiaのGraph実装 材料を揃える > Edgeを定義 grade_generation_v_documents_and_questionを定義 1. chainを定義 2. Stateからチェックするデータを取得 3. chainをinvoke 4. 文字列を出力 State • question: 使用 • datasource: • generation: 使用 • documents: 使用 事実に基づくか:no→回答の再生成 事実に基づくか:yes→ • 有益か:yes→処理終了 • 有益か:no→質問の再生成 34

Slide 36

Slide 36 text

SofiaのGraph 実装ステップ 材料を揃える Stateを定義 Nodeを定義 Edgeを定義 繋ぎ合わせる Graphを定義 Nodeを追加 Edgeを追加 構築確認 Graphをコン パイルする 35

Slide 37

Slide 37 text

SofiaのGraph実装 材料を揃える > Graphを定義 State workflowというGraphを定義 State 36

Slide 38

Slide 38 text

SofiaのGraph実装 材料を揃える > Nodeを追加 State Node名を指定してNodeを追加 decide_datasource retrieve grade_documents transform_query generate Node名 Nodeの関数 37

Slide 39

Slide 39 text

SofiaのGraph実装 材料を揃える > Edgeを追加 繋げるNodeを指定してEdgeを追加 decide_datasource retrieve grade_documents transform_query generate _start_ grade_documents_ or_generate 初めのEdgeでは STARTと書く 出力がneed to…ならgrade_documentsへ 出力がcan gene…ならgenerateへ 38

Slide 40

Slide 40 text

SofiaのGraph実装 材料を揃える > Edgeを追加 繋げるNodeを指定してEdgeを追加 decide_datasource retrieve grade_documents transform_query generate _start_ _end_ grade_documents_ or_generate decide_to_generate grade_generation_v_documents_and_question 出力がtrans…ならtransform_queryへ 出力がgene…ならgenerateへ 最後のNodeでは Endと書く 39

Slide 41

Slide 41 text

SofiaのGraph実装 構築確認 compileしてreturnしたらGraph完成! decide_datasource retrieve grade_documents transform_query generate _start_ _end_ grade_documents_ or_generate decide_to_generate grade_generation_v_documents_and_question 40

Slide 42

Slide 42 text

おまけ Graphの可視化 41

Slide 43

Slide 43 text

おまけ Graphの可視化 markdown形式で図を出力できる 42

Slide 44

Slide 44 text

社内資料検索ボット Sofia の実装 ふりかえり やること • LangGraphを用いたAIエージェントの構築 • Flaskを用いたアプリケーション全体の構築 本発表の目的 SofiaのAIエージェント構築の説明を通して LangGraphを使ったAIエージェントの構築の仕方をわかりやすくまとめる 43

Slide 45

Slide 45 text

ご清聴ありがとうございました