Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
LangChain4jを使った生成AIシステム設計パターン 〜 Javaで構築する最新アーキテクチャ
Search
鏡味秀行
October 26, 2024
3
520
LangChain4jを使った生成AIシステム設計パターン 〜 Javaで構築する最新アーキテクチャ
JJUG CCC 2024 Fall のセッション資料です。
デモは以下です
https://github.com/hide212131/langchain4j-demo
鏡味秀行
October 26, 2024
Tweet
Share
More Decks by 鏡味秀行
See All by 鏡味秀行
話題のGraphRAG、その可能性と課題を理解する
hide212131
2
530
JHipsterで爆速かつ堅牢なエンタープライズ Spring Boot 開発を実現する
hide212131
0
600
Featured
See All Featured
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
46
2.1k
VelocityConf: Rendering Performance Case Studies
addyosmani
325
24k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
27
780
What's in a price? How to price your products and services
michaelherold
243
11k
The Straight Up "How To Draw Better" Workshop
denniskardys
232
140k
The Cost Of JavaScript in 2023
addyosmani
45
6.5k
Why You Should Never Use an ORM
jnunemaker
PRO
53
9k
Embracing the Ebb and Flow
colly
84
4.4k
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
167
49k
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
27
1.9k
A better future with KSS
kneath
238
17k
Docker and Python
trallard
40
3.1k
Transcript
LangChain4jを使った生成AIシ ステム設計パターン 〜 Javaで構築する最新アーキテクチャ 経営企画本部 AI推進室 鏡味秀行 1
自己紹介 鏡味(かがみ) 秀行 (51歳) 現在: 自社の生成AIの普及展開 Java歴: Hotjava(‘95)~SI案 件15年ほど JHipsterで昨年JJUG登壇
日曜プログラミング、生成AI、 緑黄色社会、ドラム 2
本日のテーマ 生成AIを使ったシステムのアーキテクチャを学ぶ LangChain4jを通じてJava言語による生成AIシステムの 構築方法を理解 生成AIシステムの設計パターンを習得し今後の開発に活か せる 3
アジェンダ LangChain4jとLLMアーキテクチャ (15分) LLM抽象化/ Structured Outputs/ Function Calling RAG (Retrieval-Augmented
Generation) (15分) Naive RAG/ Advanced RAG AIエージェント (10分) まとめとQ&A (5分) 4
軽めのデモ あなたはLangChain4jで作られたエージェントです。 これからJJUG(ジェイジャグ)の会場でLangChain4jのセ ッションをします。 会場にいる人に自己紹介と現在時刻を伝えてください。 あなたが時刻を知っていることは珍しいので、そのこと も伝えてください。 最後に短くご挨拶をしてください。 “ “
5
デモ環境 10/18にOpenAIから出たAudio generation(従来のテキ スト用のAPIに音声も付く)をLangChain4jへQuickHack LangChain4jエージェントにて、時刻取りつつ挨拶 VSCodeでrapaio-jupyter-kernel実行 Java用のJupyter Kernel JShell実行、repo, dependency
を記述可能 6
会場の方へヒアリング システム開発をしていてLLMフレームワークを組み込んで いる方 それをJavaで開発されている方 7
LangChain4j Java用のLLMフレームワーク Python/JavaScriptの LangChainに触発 広範囲な機能をアクティブに 多様なモデルやストア対応 様々なツールの提供 SpringやQuarkusとの統合 8
その他のJavaのフレームワーク Spring AI Springファースト TestContainers周りの充実 Semantic Kernel MSのPlatformのサポート C#, Python
→ Javaポーティング 9
LLM FWのアーキテクチャ 紹介するもの: LangChain4jの他 Spring AI, Semantic Kernel for Java
など他でもサポートしている機能 ( 以降は一番メジャーなOpenAI社の機能名で説明) 1. LLMモデルなどのAPI抽象化 2. 構造データ出力 (Structured Ouputs ) 3. 関数呼び出し(Function Calling) 10
1. APIの抽象化 対応モデル: OpenAI, Azure OpenAI, Anthropic, Gemini, Ollama, etc...
以下 ️ 以外は共通 ChatLanguageModel model = OpenAiChatModel.builder() // ️ プロバイダー .apiKey("api key") // ️ APIキー .modelName(GPT_4_O_MINI) // ️ LLMモデル .build(); String answer = model.generate("「こんにちは」と言ってください"); System.out.println(answer); // → こんにちは 11
ストリーミング(流れるような文字) StreamingChatLanguageModel model = OpenAiStreamingChatModel.builder()...; model.generate("皆さんへ挨拶を一言で", new StreamingResponseHandler<AiMessage>() { //
コールバック @Override public void onNext(String token) { System.out.print(token + "|"); // |皆|さん|、|こんにちは|!| } @Override public void onComplete(Response<AiMessage> response) { } @Override public void onError(Throwable error) { } }); 12
2. Structured Outputs 天気 本⽇10/28の 天気は 曇りです。 10/28 曇り Structured
Outputs 13
2. Structured Outputs 非構造化データ から 構造データ を抽出 LangChain4jでは Structured Data
Extraction と呼 ばれる 天気 本⽇10/28の 天気は 曇りです。 10/28 曇り Structured Outputs 14
取りたい構造データの宣言 record WeatherInfo(LocalDate date, String weather) {}; 処理のインターフェースを宣言 interface WeatherForecast
{ // AiServices @SystemMessage("天気の情報を取得") WeatherInfo getWeatherInfo(String text); } 15
LLMモデルの作成 ChatLanguageModel strictModel = OpenAiChatModel.builder() .responseFormat("json_schema") // JSONスキーマ出力を強制する .strictJsonSchema(true) //
JSONスキーマ出力を強制する .build(); インスタンス化して実行 WeatherForecast forecast = AiServices.create(WeatherForecast.class, strictModel); WeatherInfo info = forecast.getWeatherInfo("明日(2024/10/28)の天気は曇りです。"); // 実行 System.out.println(info); // WeatherInfo[date=2024-10-27, weather=曇り] 16
2. Structured Outputs 欲しいJavaの型をJSON Schemaに変換して送信 LLMにスキーマを認識してもらえてエラー率が減る 部品として小回りがきく Pythonでも Instructor, Outlines
が好みの方も Pydantic(データのバリデーションや型ヒントの提 供)とJSON Schemaとの連携 ハルシネーションは起こしてしまうので対策は必須 17
AiServices (LangChain4j 固有名称) 18
Structured Outputs と AiServices Weather String 天気 10/28 曇り Weather
AiService Code ⽂字から天気情報 を 抽出するよ "本⽇10/28の天 気は曇りです" 19
AiServices による通常の対話 こんにちは。 なにかお⼿伝いできますか︖ String String こんにちは︕ Human Assistant AiService
質問に 答えるよ 20
AiServices LangChain4jの高レベルの抽象化API 概念的にはエージェント(あとの方でお話) 基本機能: Structured Outputs 機能を持つ対話型API 通常の対話 String型 →
String型 JPAのO/Rマッピングに似ている 機能のインジェクションで、エージェント能力強化 21
3. Function Calling 14:30です String String ⽇本は今何時ですか︖ Human Timekeeper AiService
LocalDateTime String 14:30 Clock #getCurrentTime (String zoneId) 時刻来たかぁ… 関数に頼ろう Asia/Tokyo 22
3. Function Calling LLMに用意された関数を実行するかを判断してもらう LLMが考えるのは 関数名 と 引数 のみ。実行はLLMの呼び 出し側で行う。
呼び出され側で行う Assistant API とは別モノ LangChain4jでは Tools と呼ばれる @Tool がついたメソッドを呼び出す 23
AiSerivices (処理のインターフェース) 宣言 interface TimeKeeper { @SystemMessage("現在の時刻を何時何分の形式で答えてください") String ask(String question);
} Function (Tool) の宣言 class Clock { // Function群 (Tools) @Tool // 呼び出したいFunction (Tool) public LocalDateTime getCurrentTime(String timeZoneId) { return LocalDateTime.now(ZoneId.of(timeZoneId)); } } 24
インスタンス化 TimeKeeper timeKeeper = AiServices.builder(TimeKeeper.class) .chatLanguageModel(model) .tools(new Clock()) // 関数(ツール)群の注入
.build(); 実行 String answer = timeKeeper.ask("今何時?"); System.out.println(answer); // 例: "現在の時刻は16時58分です" 25
Function Calling の使用場面 LLMに足りない機能を補う用途に使う 複雑な計算や統計分析、時制や地理を含む話題など LLMに制御を委ねてよい場合に使う 制御を自前でしたければ Structured Outputs を活用
LLMの処理結果を構造データで返してもらう データを見て制御を行う 26
⾃分は知らないので 外部に問い合わせよう。 結果から回答⽂は作ろう (専⾨的な回答) (専⾨的な質問) Human LLMに無い 専⾨的な 情報 問い合わせ
専⾨情報 AiService RAG 27
RAG (Retrieval-Augmented Generation) 専門知識など、LLMが知らない情報を外部より能力強化 多くは検索エンジンと組み合わせ 自然言語と相性のよいベクター検索が人気 外部情報その他: ネットの情報, RDB, GraphDB
様々な手法が日々考案(裏を返せば期待と結果のギャップ が大きい) 28
(専⾨的な回答) (専⾨的な質問) Human Vector DB Document RAG Pipline Query embedding
Chunked Txt Vec[12,-34,... Vec[11,-33,... Chunked Txt Naive RAG (Naive: 普通の) 29
Indexing ( RAG Pipiline ) (引用: https://docs.langchain4j.dev) 30
Indexing ( RAG Pipiline ) テキストを裁断してテキストチャンクに parsing, splitting, chunking テキストチャンクの意味をベクトル化
embedding DBに保存 indexing (専⾨的な回答) (専⾨的な質問) Human Vector DB Document RAG Pipline Query embedding Chunked Txt Vec[12,-34,... Vec[11,-33,... Chunked Txt 31
従来のETL(Extract/Transform/Load)ほぼ同様の概念 LLMシステムでは、より非構造データ・自然言語を対象と する傾向が強まる LlamaIndex の RAG Pipiline より データの取得(Load the
data) データの変換(Transform the data) データ索引格納(Index and store the data) 32
// parsing: RAGで使うドキュメントを読む DocumentParser documentParser = new TextDocumentParser(); Document document
= FileSystemDocumentLoader.loadDocument(toPath(documentPath), documentParser); // splitting, chunking: ドキュメントを300byteごとにチャンク分割 DocumentSplitter splitter = DocumentSplitters.recursive(300, 0); List<TextSegment> segments = splitter.split(document); 33
// embedding: チャンクの数分、float[385]のembeddingを作成 EmbeddingModel embeddingModel = new BgeSmallEnV15QuantizedEmbeddingModel(); List<Embedding> embeddings
= embeddingModel.embedAll(segments).content(); // indexing: インメモリストアに保存 EmbeddingStore<TextSegment> embeddingStore = new InMemoryEmbeddingStore<>(); embeddingStore.addAll(embeddings, segments); 34
ローダー・パーサーのバリエーション DocumentLoader: Amazon S3, Azure Blob Storage, Google Cloud Storage,
File System, URL,etc... DocumentParser: Text, Apache Tika (MSOffice(POI) / PDF(PDFBox)) Tikaがサポートするフォーマット https://tika.apache.org/3.0.0-BETA2/formats.html 構造はシンプルなので独自実装も十分可能 35
Querying (引用: https://docs.langchain4j.dev) 36
Querying 質問の意味をベクトルで数値化する embedding 類似の意味を持つ情報を取り出す retrive 抽出した情報をLLMが整理して回答する generation (専⾨的な回答) (専⾨的な質問) Human
Vector DB Document RAG Pipline Query embedding Chunked Txt Vec[12,-34,... Vec[11,-33,... Chunked Txt 37
Injection Content Retriever Human VectorDB Query embedding AiService AiServiceでRAG 38
// コンテンツ取得担当(Retriever)を用意する ContentRetriever contentRetriever = EmbeddingStoreContentRetriever.builder() .embeddingStore(embeddingStore) // ストアの注入 .embeddingModel(embeddingModel)
// モデルの注入 .build(); 39
// 質問回答アシスタントを用意する(自前で定義) public interface Assistant { String answer(String query); //
質問したら回答 } // アシスタントのプロキシを作成 Assistant assistant = AiServices.builder(Assistant.class) .chatLanguageModel(chatLanguageModel) // 回答作成用モデル .contentRetriever(contentRetriever) // Retrieverの注入 .build(); // Retrieve-Argumented Generation: 質問するとドキュメントを検索して回答 String agentAnswer = assistant.answer(userQuery); 40
Retrieval Argmentor Injection Content Retriever Human AiService Query Transformer Content
Aggregator Query Router Content Injector Advanced RAG 41
LangChain4jにおけるサポート RetrievalAugmentor: RAGプロセス全体を管理・制御 QueryTransformer : ユーザークエリを最適化 QueryRouter: 複数のRetrieverにクエリを振り分け ContentRetriever: ソースから情報取得
ContentAggregator: 取得したコンテンツを集約整理 ContentInjector: 取得したコンテンツをLLMのプロンプ トに挿入 42
QueryTransformer (専⾨的な回答) (専⾨的な質問) Human VectorDB Query embedding Vec[11,-33,... Query Transformer
(ヒットしやすい 質問) 43
QueryTransformer ベクター検索でヒットさせるため、質問を回答に近づける 質問と回答が意味的に近い「わけではない」 例:「東京の観光スポットは?」→ 「東京で最も訪れる価 値のある観光地」「東京における観光客に人気の名所」 「東京都内の有名な見どころ」 44
ContentRetriever: Text-to-SQL SQL Content Retriever Human RDB AiService ⽇本の都市を… Text
to SQL ”SELECT city FROM ... [東京, 神奈川,…] 東京や神奈川が... 45
Text-to-SQL ContentRetriever の一つ 自然言語からSQLを生成してRDBへ問い合わせ LangChain4jではSqlDatabaseContentRetrieverで試 験実装 自然言語クエリの解釈、SQLの生成と実行、エラー処理 から結果の整形して再実行 46
Text-to-SQLの様々な手法 自然言語→LLMが固定されたSQLを選択 自然言語→SQLテンプレート+LLM抽出パラメータ 自然言語→LLMがクエリの自動生成 スキーマや制約条件をLLMに与えて生成 その他、処理時間計測して最適化する例: Architectural Patterns for Text-to-SQL:
Leveraging LLMs for Enhanced BigQuery Interactions 47
セマンティックレイヤー 概念的には「ビジネスドメインの意味を もたせる層」「人間とデータの仲介」 Text-to-SQLにおける「自然言語」と 「SQLやデータ」 LangChain4j では AiService 48
AIエージェント 49
生成AIのハイプ・サイクル 引用: Gartner、「生成AIのハイプ・サイクル:2024年」を 発表 より 50
AIエージェントとはなにか ユーザの代理として自律的(プロアクティブ)に実行する 実行計画を自分で立てる 自ら実行する 反省し学習し適応する 51
AIエージェントはなぜ必要? 複雑で動的な問題の自律的解決 ビジネス環境の不確実性が高く、全てを事前に予測困難 状況に応じて臨機応変にスケーラブルに対応 できることはAIに委譲し、限られた人的リソースは創造的 で価値の高いことに使いたい 52
Agentic Design Patterns https://www.deeplearning.ai/ (Andrew Ng先生)より リフレクション: LLMの自己評価、性質の異なるLLMによ る相互評価、改善し再実行 ツールの利用:
外部ツールやAPIの活用(Function Calling やRAG) 計画と実行: 目標設定とタスク分割 マルチエージェント: エージェント同士の協力でタスク実 行 53
START END Coding Test Code Test Comp? 計画と実行 LangChainのブログ'Planning for
Agents'より 「PDCAプロセスをイチから考えて」 のLLMへの丸投げは今は辛み 人間がより具体化する必要 ドメイン固有の認知アーキテクチャ 状況把握と指示→状態遷移マシン ブログでは LangGraph を推奨 54
マルチエージェント DeepLearning.AIのAgentic Design Patterns Part 5, Multi-Agent Collaborationより 一つのLLMよりも、多様な意見を持つLLMに議論させたほ うが良い推論ができる
LLMは人間と同じで、長く煩雑で雑多な指示が苦手 役割ごとに細分化する 例)システムプロンプトで「あなたは◦◦のエキスパー トです」を複数立てる 55
LangChain4jでAgent こいつです→AiServices 自律的に判断して行動 外部情報取得 Function Calling, RAG 今後よりエージェント対応していくと予想 計画と実行のための状態遷移マシン 発展途上だが
LangGraph4j 56
LangChain4j + LangGraph4j Judge! Pros Cons START END Debate! 57
アーキテクチャスタイル LLMをツールとして使うか、エージェント として使うか 制御を手前か奥か Weather String 天気 10/28 曇り Weather
AiService Code ⽂字から天気情報 を 抽出するよ "本⽇10/28の天 気は曇りです" Retrieval Argmentor Injection Content Retriever Human AiService Query Transformer Content Aggregator Query Router Content Injector 58
本日説明しきれなかったところ システム評価と改善 LLMの出力品質を評価し最適化を行うフィードバックル ープの構築 Javaではスタンダートなものは無く、しばらくはPython などのツールを使っていくことに 59
Java+LLMについての思い 舞台は整っている: 環境は整備され学習コストも低い JavaがあればJavaに: エンタープライズ系、既存システム のエンハンス 溜めたスキル活かす: 皆さまがこれまで習得したスキルが むしろ大事、そのままLLMシステムに活かせる LangChain4j:
オススメですが、あくまで一つの代表例。 他のフレームワークも触っていただければ ️ 60
Spring Boot + LangChain4j 手軽にSpring BootでLangChain4jを試したかったら 拙作の JHipster LLM も触ってみてください
https://github.com/hide212131/generator-jhipster-llm 以下のコマンドで実行環境ができます。 jhipster-llm generate-sample sample --llm-framework langchain4j 61
Q&A 62
ご清聴ありがとうございました! 63