昨年、 周り これは急速に成長するプロジェクトで、アップデートに精通したいのですが、LangChain4Jにモデルコンテキスト プロトコル サーバーを統合する方法も調べてみました。 I started to dig a bit ラングチェーン4J バージョン1 Beta 私は2024年11月に最後の投稿を書いたが、その時点で利用可能な最新バージョン、v0.35 を使用した。 Date Release September 25th, 2024 0.35.0 December 22th, 2024 1.0.0-alpha1 February 10th, 2025 1.0.0-beta1 March 13th, 2025 1.0.0-beta2 April 12th, 2025 1.0.0-beta3 2024年9月25日 トップ > 35.0 2024年12月22日 1.0.0 アルファ1 2月10日、2025 1.0.0 ベータ1 3月13日、2025 1.0.0 ベータ2 4月12日、2025 1.0.0 ベータ3 ラングチェーン4J メンテナイナーはこの機会を利用して、破壊的な変更を導入しました。私の場合、私は破壊的なAPIの変更をカウントするためにコードを更新しなければなりませんでした。 セム v0.35 v1.0.0-beta3 val s = Sinks.many() .unicast() .onBackpressureBuffer<String>() chatBot.talk(m.sessionId, m.text) .onNext(s::tryEmitNext) .onError(s::tryEmitError) .onComplete { s.tryEmitComplete() }.start() return ServerResponse.ok().bodyAndAwait( s.asFlux().asFlow() ) val s = Sinks.many() .unicast() .onBackpressureBuffer<String>() chatBot.talk(m.sessionId, m.text) .onPartialResponse(s::tryEmitNext) .onError(s::tryEmitError) .onCompleteResponse { s.tryEmitComplete() }.start() return ServerResponse.ok().bodyAndAwait( s.asFlux().asFlow() ) シンクス(SINKS.MANY) ユニクロ( .onBackpressureバッファ<String>() chatBot.talk(m.sessionId、m.text) .onNext(s::tryEmitNext) エラー(s::tryEmitError) 満員です。 トップ > トップ > トップ > スタート( ) トップ > トップ > トップ > トップ > トップ > トップ > トップ > トップ > トップ > ( トップ > トップ > トップ > トップ > トップ > トップ ) シンクス(SINKS.MANY) ユニクロ( .onBackpressureバッファ<String>() chatBot.talk(m.sessionId、m.text) .onPartialResponse(s::tryEmitNext) エラー(s::tryEmitError) 答えを満たす。 トップ > トップ > トップ > スタート( ) トップ > トップ > トップ > トップ > トップ > トップ > トップ > トップ > トップ > ( トップ > トップ > トップ > トップ > トップ > トップ ) プロジェクト Reactor Integration LangChain4JはProject Reactorの統合を提供しています; 私は以前のミュージングでそれを逃した。 . a lot I am using , so I previously defined an interface for LangChain4J to implement at runtime: ランタイムで実装するためのインターフェイスを定義しました。 AiServices interface ChatBot { fun talk(@MemoryId sessionId: String, @UserMessage message: String): TokenStream } 次に次のような依存性を挙げます。 <dependency> <groupId>dev.langchain4j</groupId> <artifactId>langchain4j-reactor</artifactId> <version>1.0.0-beta3</version> </dependency> 返品タイプを A から変更できます。 2 A 以下、更新した署名です。 Flux<String> TokenStream interface ChatBot { fun talk(@MemoryId sessionId: String, @UserMessage message: String): Flux<String> } それは創造の実現である。 上記のコードは以下のように簡素化できます。 sink val flux = chatBot.talk(m.sessionId, m.text) ServerResponse.ok().bodyAndAwait(flux.asFlow()) デバッグの2日間は簡単にドキュメンタリーを読む2時間を節約できることを覚えておいてください! 私は後者をしなかった。 モデル コンテキスト プロトコル サーバーの統合 このセクションでは、私のLangChain4Jアプリケーションに<abbr title="Model Context Protocol">MCP</abbr>を統合したい。 「Retrieval-Augmented Generation」 多くのリソースを必要とします <abbr title="Large Language Model">LLM</abbr>を訓練する:それは直接時間と金に翻訳されます。このため、企業は新しいモデルのバージョンの訓練を制限します。 モデルの関連性は、情報が蓄積し、変化するにつれて時間とともに減少し、LLMのデータベースは不変です。 さらに、LLMは公的データに訓練されています。 Retrieval Augmented Generation は 2 段階のプロセスです. 最初のステップでは、ツールはデータを解析し、LLM に従ってベクトル化し、ベクトルデータベースに保存し、第二に、ツールはLLM をクエリするときにデータベースを追加データとして使用します. コンテキスト プロトコル LLMの静的性質を処理する最新の方法は、MCPです。 MCP は、アプリケーションが LLM にコンテキストを提供する方法を標準化するオープン プロトコルです。AI アプリケーションのための USB-C ポートのように MCP を考えてください. Just as USB-C provides a standardized way to connect your devices to various peripherals and accessories, MCP provides a standardized way to connect AI models to different data sources and tools. -- モデル コンテキスト プロトコルから始める MCP は、アプリケーションが LLM にコンテキストを提供する方法を標準化するオープン プロトコルです。AI アプリケーションのための USB-C ポートのように MCP を考えてください. Just as USB-C provides a standardized way to connect your devices to various peripherals and accessories, MCP provides a standardized way to connect AI models to different data sources and tools. ── モデル・コンテキスト・プロトコルから始める MCP は RAG に対して 2 つの利点があります。 Data processed by a RAG is tailored for a model. If one wants to use a new model, one must re-execute the parsing phase. MCP standardizes the interactions between a client and a server, making them technology-independent. RAG allows the reading of data. MCP allows any API call to either access data dynamically ! or execute actions MCP 定義 クライアント・サーバー通信: 2 交通手段 stdio: クライアントはサブプロセスを起動し、通信は標準内および標準外で行われます。 HTTP with Server-Sent イベント ソリューションのアーキテクチャ 上記の理論に従って、私たちは今、MCPサーバを選択することから始まります。 いいスタートだったけど、選びました。 なぜなら、LangChain4Jのドキュメンタリーがそれを言及しているからです。 こちら GitHub MCP サーバー GitHub MCP サーバーは、 輸送. それは私たちがバイナリを取得し、アプリケーションから始めることを意味します. それは HTTP 輸送に比べて速いが、モデルへの HTTP 呼び出しとその側の計算時間を含む全体的な時間を考慮して、それは無関係です. アーキテクチャの観点から、私はそのプロセスと専用のコンポーネントを好む。 スタジオ いくつかの研究を経て、私はその プロジェクト. それは、スタジオからHTTPまたはHTTPからスタジオの間を切り替えることを可能にします. それはまた、ドッカーイメージとして利用できます. 我々は、次のとおり、サーバーとプロキシの両方を組み合わせることができます : mcpプロキシ Dockerfile FROM ghcr.io/sparfenyuk/mcp-proxy:latest ENV VERSION=0.2.0 ENV ARCHIVE_NAME=github-mcp-server_Linux_x86_64.tar.gz RUN wget https://github.com/github/github-mcp-server/releases/download/v$VERSION/$ARCHIVE_NAME -O /tmp/$ARCHIVE_NAME \ #1 && tar -xzvf /tmp/$ARCHIVE_NAME -C /opt \ #2 && rm /tmp/$ARCHIVE_NAME #3 RUN chmod +x /opt/github-mcp-server #4 ダウンロード Archive を抽出 ファイルを削除 オリジナルタイトル: Make the Binary Executable を定義できないことに留意してください。 バイナリーはパラメータでポートとホストを構成することを許可しているため、このため、我々はランタイム時にコマンドを延期しなければなりません。 : CMD docker-compose.yaml services: mcp-server: build: context: github-mcp-server env_file: - .env #1 command: - --pass-environment #2 - --sse-port=8080 #3 - --sse-host=0.0.0.0 #4 - -- #5 - /opt/github-mcp-server #6 - --toolsets - all - stdio GITHUB_PERSONAL_ACCESS_TOKEN 環境変数と有効なトークンが必要です。 すべての環境変数をサブプロセスに転送する Listening Port の設定 すべてのIPに接続する The proxy "connects" to the stdio MCP server after the dash すべてのオプションを有効にしたサーバーを実行 画像は、The image will provide the 端末は8080ポート。 /sse ソリューションのコード化 コードの部分は最も簡単です ダウンロードへ プロジェクトでは、以下のように翻訳されます。 LangChain4J MCP ドキュメンタリー bean { val transport = HttpMcpTransport.Builder() .sseUrl(ref<ApplicationProperties>().mcp.url) //1 .logRequests(true) //2 .logResponses(true) //2 .build() val mcpClient = DefaultMcpClient.Builder() .transport(transport) .build() mcpClient.listTools().forEach { println(it) } //3 McpToolProvider.builder() .mcpClients(listOf(mcpClient)) .build() } bean { coRouter { val chatBot = AiServices .builder(ChatBot::class.java) .streamingChatLanguageModel(ref<StreamingChatLanguageModel>()) .chatMemoryProvider { MessageWindowChatMemory.withMaxMessages(40) } .contentRetriever(EmbeddingStoreContentRetriever.from(ref<EmbeddingStore<TextSegment>>())) .toolProvider(ref<McpToolProvider>()) //4 .build() POST("/")(PromptHandler(chatBot)::handle) } } ConfigurationProperty クラスを追加して SSE URL をパラメータ化しました。 MCP プロトコルは、ログをクライアントに送信する方法を提供します。 必要ではありませんが、クライアントがサーバーに接続されていることを確認し、提供されたツールをリストすることができます。 AiServices で上に作成された MCP ツール プロバイダーにプラグインします。 この時点で、モデルは、登録されたツールのいずれかに匹敵するリクエストをMCPサーバーに送信する必要があります。 curl -N -H 'Content-Type: application/json' localhost:8080 -d '{ "sessionId": "1", "text": "What are my top three most popular GitHub repos?" }' 何度も試してみたのですが、こういう答えをいただきました。 Unfortunately, the provided text does not contain any information about your top three most popular GitHub repositories. The text appears to be a blog post or a personal website, and it mentions some of your projects and experiences with GitHub, but it does not provide any metrics or statistics on the popularity of your repositories. If you want to know more about the popularity of your GitHub repositories, I would recommend checking out GitHub's own analytics tools, such as GitHub Insights or the Repository Insights API. These tools can provide information about the number of followers, stars, and forks for each repository, as well as other metrics like engagement and activity. モデルは、文書が反対を主張しているにもかかわらず、ツールを無視した。 解決策の修正 私はLangChain4Jのドキュメンタリーを数回読んだが、何の役にも立たない。私はOpenAIとほかのいくつかのAIツールを使用しようとしたが、成功しなかった。ほとんどの回答は、それは箱の外で働くべきであると確認した。ある人々は、ツールを直接呼び出し、その目的を打ち負かすと述べた。ある人はOllamaがツールをサポートしていないと述べた。私はOllamaのブログをチェックした:2024年にツールのサポートを発表した。 切り離されたアーキテクチャは、より多くの動くパーツを導入します. I suspected something might be wrong in the entire call chain. I removed the MCP proxy, added the 直接アプリケーションイメージに、HTTPからスタジオにコードを変更しました。 github-mcp-server I was about to give up when I decided to come back to the roots. I copied-pasted the うん!あれ!あれ!あれ!あれ!あれ!あれ!あれ!あれ!あれ!あれ!あれ!あれ!あれ!あれ!あれ!あれ!あれ!あれ!あれ!あれ!あれ!あれ!あれ!あれ!あれ! ドキュメンタリーからサンプル サンプルはOpenAIを使用していましたが、私はOllamaを使用していました。OpenAI、Mistral AI、OllamaでMCPを試してみました。OpenAIモデルだけがMCPで動作します。 curl -N -H 'Content-Type: application/json' localhost:8080 -d '{ "sessionId": "1", "text": "What are my top three most popular GitHub repos?" }' OpenAI はリクエストを正しいツールに正しくマッピングし、期待していた答えを返します。 Here are my findings regarding your top three most popular GitHub repositories: 1. **[opentelemetry-tracing](https://github.com/nfrankel/opentelemetry-tracing)** - **Description**: Demo for end-to-end tracing via OpenTelemetry. - **Stars**: 68 - **Forks**: 25 - **Open Issues**: 10 2. **[kaadin](https://github.com/nfrankel/kaadin)** - **Description**: Kotlin DSL for Vaadin. - **Stars**: 44 - **Forks**: 12 - **Open Issues**: 3 3. **[jvm-controller](https://github.com/nfrankel/jvm-controller)** - **Description**: Example on how to write a Kubernetes controller in Java. - **Stars**: 33 - **Forks**: 10 - **Open Issues**: 0 These repositories demonstrate a range of your interests and contributions in the areas of observability, Kotlin development, and Kubernetes.% MCP サーバーに認証トークンを送信し、それを GitHub API に送信するため、後者はどのユーザーが呼び出しをするかを知っています。 上記のクエリの一部です. 私は、複数のユーザーに対応する通常のウェブアプリケーションの異常な使用ケースであることを認めますが、それぞれ1つの認証トークンを使用します. However, it perfectly fits the use case of a desktop application. my repos その他のよくある質問は、 GitHub で最も人気のあるリポジトリを見つけて、Web アプリケーションに関連しているため、暗示的な文脈 - ユーザーを持っていない。 エジ 結論 この投稿の主な焦点は、LangChain4JアプリにMCPサーバを統合することです。 まず、MCP サーバがあなたのアーキテクチャにどのように適合するかは、まだあなた次第です。 次に、LangChain4Jは漏れのある抽象であるように見えます. それはあなたに強力な抽象層を提供するためにあらゆることを可能にするが、その下であなたを守る実装は等しくありません. I wish the documentation would mention it, although I understand the current version is in beta. mcp-proxy 実際の世界でMCPについて学び、プロジェクトアイデアにいくつかの扉を開いた。 この記事の完全なソースコードはこちらでご覧いただけます。 . GitHub To go further: モデル・コンテキスト・プロトコルから始める 素晴らしい MCP サーバーとクライアントを見つける LangChain4J - モデル・コンテキスト・プロトコル(MCP) オリジナルの投稿 A Java Geek on April 27, 2025 ・Java Geek