Slide 1

Slide 1 text

RAGをテーマに考える、LLMの認知アーキテクチャと ソフトウェア設計 Takuya Kikuchi / Algomatic シゴラクAIカンパニー CTO 2024-06-19 - LLM Night 〜⽣成AIソフトウェアアーキテクチャ〜

Slide 2

Slide 2 text

フィンテックスタートアップにおいて開発リー ドやVPoEとして開発組織構築を担当したほか、 モバイルオーダープラットフォームを⼿がける Showcase GigではVPoTとして技術領域全般を 管掌。2024年、AlgomaticにカンパニーCTOと して参画。ソフトウェア開発、設計、ドット絵 が好き X: @_pochi Algomatic シゴラクAIカンパニー CTO 菊池 琢弥 / Takuya Kikuchi 2 © 2024 Algomatic Inc.

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

No content

Slide 5

Slide 5 text

No content

Slide 6

Slide 6 text

❶ RAGとは ❷ RAGつくってみた ❸ 認知アーキテクチャとLangGraph ❹ まとめ 6 アジェンダ

Slide 7

Slide 7 text

RAGとは 7

Slide 8

Slide 8 text

RAGとは ● 外部のデータベースや知識をもとにした回答を⼤規模⾔語モデルに⽣成させ る技術 © 2024 Algomatic Inc. 8 Algomatic 社内 ドキュメント 経費申請 どうしたらいい? ⼀般的にはこうだよ! 経費申請 どうしたらいい? このフォームから必要事 項を記⼊して送ってね! 検索 検索結果 RAGなし RAGあり

Slide 9

Slide 9 text

RAGとは ● RAGの営みをざっくり整理すると ○ ユーザーの発話から「何を知りたいのか」を認識し ○ 答えるために必要な情報を検索し ○ 検索結果を踏まえ、正しくわかりやすい回答を⽣成する © 2024 Algomatic Inc. 9 Algomatic 社内 ドキュメント 引っ越しました! このフォームから住所変 更してね! 検索 検索結果

Slide 10

Slide 10 text

RAGつくってみた 10 (結構細かい話をしますが、  雰囲気を感じていただければいいな、という意図でお話します)

Slide 11

Slide 11 text

© 2024 Algomatic Inc. 11 まずはピュアに実装してみる async function answer( // ユーザー入力 message: Message, // チャット履歴 history: Message[]) { // ナレッジベースから知識を取得 const knowledge = await knowledgeBase.search(message); // LLMを呼び出して回答を生成し、回答 return await llm.call(message, history, knowledge); }

Slide 12

Slide 12 text

© 2024 Algomatic Inc. 12 そこそこ良い感じに動く が、ここからが戦いの始まりである → 回答精度のチューニングが始まる

Slide 13

Slide 13 text

© 2024 Algomatic Inc. 13 精度評価結果から、改善案を考える 検索精度に課題が⼤きいことがわかったので、そこを⾼める⼯夫をする 1. 検索⽤のクエリ改善 2. 質問への仮回答⽂を⽣成し、それをクエリに検索する(HyDE) async function answer2(message: Message, history: Message[], useHyDE: boolean) { // 検索精度を高めるためにクエリを整形する const refinedMessage = await refineQuery(message, history); // HyDEモードの場合、HyDEを使ってクエリを生成する const searchQuery = useHyDE ? await hydeQuery(refinedMessage) : refinedMessage; // ナレッジベースから知識を取得 const knowledge = await knowledgeBase.search(searchQuery); // LLMを呼び出して回答を生成 return await llm.call(message, history, knowledge); }

Slide 14

Slide 14 text

© 2024 Algomatic Inc. 14 まだまだ改善は続く RefineQuery →  良い感じ。採⽤。 HyDE →  精度向上はあるものの回答にかかる時間が⻑くなり、体験悪化。オ プション式にする。 検索精度は依然として課題 → 検索空間を狭めるために「カテゴリ」という概念を導⼊してみる

Slide 15

Slide 15 text

© 2024 Algomatic Inc. 15 「カテゴリ推定」、「ユーザーに逆質問」という遷移が追加 async function answer3(message: Message, history: Message[], useHyDE: boolean) { // 検索精度を高めるためにクエリを整形する const refinedMessage = await refineQuery(message, history); // カテゴリを推定する const estimatedCategory = await decideCategory(refinedMessage); // カテゴリが推定できなかった場合、質問内容をもう少し詳しく教えるように促す if (!estimatedCategory) { return "質問内容について、もう少し詳しく教えてください。 "; } // HyDEモードの場合、HyDEを使ってクエリを生成する const searchQuery = useHyDE ? await hydeQuery(refinedMessage) : refinedMessage; // ナレッジベースから知識を取得 const knowledge = await knowledgeBase.search(searchQuery); // LLMを呼び出して回答を生成 return await llm.call(message, history, knowledge); }

Slide 16

Slide 16 text

© 2024 Algomatic Inc. どんどん複雑化する実装 そろそろ「設計」をしよう 16

Slide 17

Slide 17 text

© 2024 Algomatic Inc. RAGシステムの複雑さを考える これまでの実装で複雑なところは... ● 各ノードの実⾏処理 ○ プロンプトエンジニアリング ○ ナレッジ検索精度 ● 判断と状態遷移 ○ こんなとき、ユーザーに聞き返すべき? ○ こうなったらもう回答を⽣成すべき? 17

Slide 18

Slide 18 text

© 2024 Algomatic Inc. RAGシステムの複雑さを考える これまでの実装で複雑なところは... ● 各ノードの実⾏処理 ○ プロンプトエンジニアリング ○ ナレッジ検索精度 ● 判断と状態遷移 ○ こんなとき、ユーザーに聞き返すべき? ○ こうなったらもう回答を⽣成すべき? 18

Slide 19

Slide 19 text

© 2024 Algomatic Inc. RAGシステムの複雑さを考える これまでの実装で複雑なところは... ● 各ノードの実⾏処理 ○ プロンプトエンジニアリング ○ ナレッジ検索精度 ● 判断と状態遷移 ○ こんなとき、ユーザーに聞き返すべき? ○ こうなったらもう回答を⽣成すべき? 19

Slide 20

Slide 20 text

© 2024 Algomatic Inc. 複雑さに⽴ち向かうには 複雑なルールを宣⾔的に記述することで保守性は向上する 20

Slide 21

Slide 21 text

© 2024 Algomatic Inc. 宣⾔的に記述してみた 21 “実⾏” と “判断” を宣⾔的に記述するようにしてみる class EstimateCategoryNode implements Node { process(state: AgentState) { // カテゴリ推定する機能を実装 } plan(state: AgentState) { // カテゴリ判定に成功したかどうかを判定し、次の遷 移先を決定 if (state.推定成功()) { return nodeOf("ナレッジ検索"); } else { return nodeOf("ユーザーに逆質問 "); } } } class RAG { ... async run() { while (true) { const node = this.currentNode; node.process(); this.currentNode = node.plan(); if(currentNode === END) { return state; } } } } const rag = new RAG([ new EstimateCategoryNode(), new RetrieveKnowledgeNode(), ...]) const result = await rag.run(); 実⾏と遷移の定義 ノードを取りまとめるクラス RAG機能の呼び出し

Slide 22

Slide 22 text

© 2024 Algomatic Inc. どうだった? かなり実装および改善がしやすくなった ● 「実⾏」と「遷移」が明確に分離されることで開発およびテストが容易に なった ○ 「検索処理を新しいバージョンに⼊れ替えて試してみるか」 などの実験も容易に ● 状態遷移図がそのまま実装されているので、開発メンバー以外との仕様に 関するディスカッションもしやすくなった 22

Slide 23

Slide 23 text

認知アーキテクチャとLangGraph 23

Slide 24

Slide 24 text

© 2024 Algomatic Inc. 認知アーキテクチャ OpenAI's Bet on a Cognitive Architecture - LangChain Blog https://blog.langchain.dev/openais-bet-on-a-cognitive-architecture/ 24 AIがどのように情報を処理し、理解し、⾏動を決定するかという根本的なフ レームワーク

Slide 25

Slide 25 text

© 2024 Algomatic Inc. 認知アーキテクチャ 25 種別 処理のアウト プット 次の処理選択 利用可能なシー ケンス Code コードで記述 コードで記述 コードで記述 LLM Call LLMによる応答 (単一呼び出し) コードで記述 コードで記述 Chain LLMによる応答 (複数呼び出し) コードで記述 コードで記述 Router LLMによる応答 LLMによる選択 (ただしループはしない) コードで記述 StateMachine LLMによる応答 LLMによる選択 (ループあり) コードで記述 Agent LLMによる応答 LLMによる選択 LLMによる定義

Slide 26

Slide 26 text

© 2024 Algomatic Inc. 認知アーキテクチャ 26 種別 処理のアウト プット 次の処理選択 利用可能なシー ケンス Code コードで記述 コードで記述 コードで記述 LLM Call LLMによる応答 (単一呼び出し) コードで記述 コードで記述 Chain LLMによる応答 (複数呼び出し) コードで記述 コードで記述 Router LLMによる応答 LLMによる選択 (ただしループはしない) コードで記述 StateMachine LLMによる応答 LLMによる選択 (ループあり) コードで記述 Agent LLMによる応答 LLMによる選択 LLMによる定義 LLMを使わないアプ リケーション Assistant API / GPTs

Slide 27

Slide 27 text

© 2024 Algomatic Inc. 認知アーキテクチャ 27 種別 処理のアウト プット 次の処理選択 利用可能なシー ケンス Code コードで記述 コードで記述 コードで記述 LLM Call LLMによる応答 (単一呼び出し) コードで記述 コードで記述 Chain LLMによる応答 (複数呼び出し) コードで記述 コードで記述 Router LLMによる応答 LLMによる選択 (ただしループはしない) コードで記述 StateMachine LLMによる応答 LLMによる選択 (ループあり) コードで記述 Agent LLMによる応答 LLMによる選択 LLMによる定義 RAGは現状これ が多い

Slide 28

Slide 28 text

© 2024 Algomatic Inc. LangGraph 認知アーキテクチャにおける、StateMachineを実装するためのライブラリ NodeとEdge、およびStateを 定義することで、宣⾔的に StateMachineを実装できる 28 const workflow = new StateGraph({ channels: graphState }); workflow.addNode("カテゴリ推定", (state: AgentState) => { // カテゴリ推定処理を記述 }); workflow.addNode("ナレッジ検索", (state: AgentState) => { // ナレッジ検索処理を記述 }); workflow.addEdge(START, "カテゴリ推定"); workflow.addConditionalEdges("カテゴリ推定", (state: AgentState) => { if (state.カテゴリ推定成功 ()) { return "ナレッジ検索"; } return "再質問"; });

Slide 29

Slide 29 text

まとめ 29

Slide 30

Slide 30 text

© 2024 Algomatic Inc. まとめ RAGシステム、最初はシンプルだが、やがて複雑なアプリケーションに変貌して いく。 ● 「アクション」と「状態遷移」そのものが関⼼ごと ○ それらを変更しやすいアーキテクチャを⽬指そう これらはRAGに限らず、LLMを活⽤する場合によく直⾯する ● LLMは「動かしてみないとわからない」ことが多い ○ 状態遷移やアクションは頻繁に変更したくなる ○ ⾼速な試⾏錯誤がプロダクトの優位性にもつながる 30

Slide 31

Slide 31 text

© 2024 Algomatic Inc. まとめ (2) ⼀⽅、LLMアプリケーションのパターンを分類した「認知アーキテクチャ」とい う概念がある ● StateMachineパターンの実装を⼿助けするLangGraphが便利そう ● RAGの実装経験から検討した設計とも合致 31

Slide 32

Slide 32 text

© 2024 Algomatic Inc. 典型的な業務システム設計の営み ValueObjectを起点としたボトムアップでの設計‧実装 32

Slide 33

Slide 33 text

RAG、ほんとうに必要ですか 「有給休暇って何⽇ですか」 → これは社内ドキュメントを検索したほうが早い 33

Slide 34

Slide 34 text

RAG、ほんとうに必要ですか RAGが「ありがたい」となるケースを考える 1. 「何がわからないかわからない → 検索クエリも思い浮かばない状態 2. 複数の情報ソースを統合する → 引っ越したけどどうしたら? 3. 対話形式での情報取得 → プログラミングなど 34