Upgrade to Pro — share decks privately, control downloads, hide ads and more …

LangChain4jを使った生成AIシステム設計パターン 〜 Javaで構築する最新アーキテクチャ

鏡味秀行
October 26, 2024
520

LangChain4jを使った生成AIシステム設計パターン 〜 Javaで構築する最新アーキテクチャ

JJUG CCC 2024 Fall のセッション資料です。
デモは以下です
https://github.com/hide212131/langchain4j-demo

鏡味秀行

October 26, 2024
Tweet

Transcript

  1. アジェンダ LangChain4jとLLMアーキテクチャ (15分) LLM抽象化/ Structured Outputs/ Function Calling RAG (Retrieval-Augmented

    Generation) (15分) Naive RAG/ Advanced RAG AIエージェント (10分) まとめとQ&A (5分) 4
  2. LLM FWのアーキテクチャ 紹介するもの: LangChain4jの他 Spring AI, Semantic Kernel for Java

    など他でもサポートしている機能 ( 以降は一番メジャーなOpenAI社の機能名で説明) 1. LLMモデルなどのAPI抽象化 2. 構造データ出力 (Structured Ouputs ) 3. 関数呼び出し(Function Calling) 10
  3. 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
  4. ストリーミング(流れるような文字) 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
  5. 2. Structured Outputs 非構造化データ から 構造データ を抽出 LangChain4jでは Structured Data

    Extraction と呼 ばれる 天気 本⽇10/28の 天気は 曇りです。 10/28 曇り Structured Outputs 14
  6. 取りたい構造データの宣言 record WeatherInfo(LocalDate date, String weather) {}; 処理のインターフェースを宣言 interface WeatherForecast

    { // AiServices @SystemMessage("天気の情報を取得") WeatherInfo getWeatherInfo(String text); } 15
  7. 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
  8. 2. Structured Outputs 欲しいJavaの型をJSON Schemaに変換して送信 LLMにスキーマを認識してもらえてエラー率が減る 部品として小回りがきく Pythonでも Instructor, Outlines

    が好みの方も Pydantic(データのバリデーションや型ヒントの提 供)とJSON Schemaとの連携 ハルシネーションは起こしてしまうので対策は必須 17
  9. Structured Outputs と AiServices Weather String 天気 10/28 曇り Weather

    AiService Code ⽂字から天気情報 を 抽出するよ "本⽇10/28の天 気は曇りです" 19
  10. 3. Function Calling 14:30です String String ⽇本は今何時ですか︖ Human Timekeeper AiService

    LocalDateTime String 14:30 Clock #getCurrentTime (String zoneId) 時刻来たかぁ… 関数に頼ろう Asia/Tokyo 22
  11. 3. Function Calling LLMに用意された関数を実行するかを判断してもらう LLMが考えるのは 関数名 と 引数 のみ。実行はLLMの呼び 出し側で行う。

    呼び出され側で行う Assistant API とは別モノ LangChain4jでは Tools と呼ばれる @Tool がついたメソッドを呼び出す 23
  12. 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
  13. インスタンス化 TimeKeeper timeKeeper = AiServices.builder(TimeKeeper.class) .chatLanguageModel(model) .tools(new Clock()) // 関数(ツール)群の注入

    .build(); 実行 String answer = timeKeeper.ask("今何時?"); System.out.println(answer); // 例: "現在の時刻は16時58分です" 25
  14. (専⾨的な回答) (専⾨的な質問) Human Vector DB Document RAG Pipline Query embedding

    Chunked Txt Vec[12,-34,... Vec[11,-33,... Chunked Txt Naive RAG (Naive: 普通の) 29
  15. 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
  16. // 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
  17. // 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
  18. ローダー・パーサーのバリエーション 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
  19. // 質問回答アシスタントを用意する(自前で定義) 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
  20. ContentRetriever: Text-to-SQL SQL Content Retriever Human RDB AiService ⽇本の都市を… Text

    to SQL ”SELECT city FROM ... [東京, 神奈川,…] 東京や神奈川が... 45
  21. Agentic Design Patterns https://www.deeplearning.ai/ (Andrew Ng先生)より リフレクション: LLMの自己評価、性質の異なるLLMによ る相互評価、改善し再実行 ツールの利用:

    外部ツールやAPIの活用(Function Calling やRAG) 計画と実行: 目標設定とタスク分割 マルチエージェント: エージェント同士の協力でタスク実 行 53
  22. START END Coding Test Code Test Comp? 計画と実行 LangChainのブログ'Planning for

    Agents'より 「PDCAプロセスをイチから考えて」 のLLMへの丸投げは今は辛み 人間がより具体化する必要 ドメイン固有の認知アーキテクチャ 状況把握と指示→状態遷移マシン ブログでは LangGraph を推奨 54
  23. マルチエージェント DeepLearning.AIのAgentic Design Patterns Part 5, Multi-Agent Collaborationより 一つのLLMよりも、多様な意見を持つLLMに議論させたほ うが良い推論ができる

    LLMは人間と同じで、長く煩雑で雑多な指示が苦手 役割ごとに細分化する 例)システムプロンプトで「あなたは◦◦のエキスパー トです」を複数立てる 55
  24. アーキテクチャスタイル 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
  25. Spring Boot + LangChain4j 手軽にSpring BootでLangChain4jを試したかったら 拙作の JHipster LLM も触ってみてください

    https://github.com/hide212131/generator-jhipster-llm 以下のコマンドで実行環境ができます。 jhipster-llm generate-sample sample --llm-framework langchain4j 61