昨年、I started to dig a bit周りラングチェーン4Jこれは急速に成長するプロジェクトで、アップデートに精通したいのですが、LangChain4Jにモデルコンテキスト プロトコル サーバーを統合する方法も調べてみました。
バージョン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() |
val s = Sinks.many() |
シンクス(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 usingAiServices
, so I previously defined an interface for LangChain4J to implement at runtime: ランタイムで実装するためのインターフェイスを定義しました。
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 から変更できます。Flux<String>
2 ATokenStream
以下、更新した署名です。
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サーバを選択することから始まります。こちらいいスタートだったけど、選びました。GitHub MCP サーバーなぜなら、LangChain4Jのドキュメンタリーがそれを言及しているからです。
GitHub MCP サーバーは、スタジオ輸送. それは私たちがバイナリを取得し、アプリケーションから始めることを意味します. それは HTTP 輸送に比べて速いが、モデルへの HTTP 呼び出しとその側の計算時間を含む全体的な時間を考慮して、それは無関係です. アーキテクチャの観点から、私はそのプロセスと専用のコンポーネントを好む。
いくつかの研究を経て、私はそのmcpプロキシプロジェクト. それは、スタジオからHTTPまたはHTTPからスタジオの間を切り替えることを可能にします. それはまた、ドッカーイメージとして利用できます. 我々は、次のとおり、サーバーとプロキシの両方を組み合わせることができます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/sse
端末は8080ポート。
ソリューションのコード化
コードの部分は最も簡単です ダウンロードへ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 thegithub-mcp-server
直接アプリケーションイメージに、HTTPからスタジオにコードを変更しました。
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 に送信するため、後者はどのユーザーが呼び出しをするかを知っています。my repos上記のクエリの一部です. 私は、複数のユーザーに対応する通常のウェブアプリケーションの異常な使用ケースであることを認めますが、それぞれ1つの認証トークンを使用します. However, it perfectly fits the use case of a desktop application.
その他のよくある質問は、エジGitHub で最も人気のあるリポジトリを見つけて、Web アプリケーションに関連しているため、暗示的な文脈 - ユーザーを持っていない。
結論
この投稿の主な焦点は、LangChain4JアプリにMCPサーバを統合することです。
まず、MCP サーバがあなたのアーキテクチャにどのように適合するかは、まだあなた次第です。mcp-proxy
次に、LangChain4Jは漏れのある抽象であるように見えます. それはあなたに強力な抽象層を提供するためにあらゆることを可能にするが、その下であなたを守る実装は等しくありません. I wish the documentation would mention it, although I understand the current version is in beta.
実際の世界でMCPについて学び、プロジェクトアイデアにいくつかの扉を開いた。
この記事の完全なソースコードはこちらでご覧いただけます。GitHub.
To go further:
- モデル・コンテキスト・プロトコルから始める
- 素晴らしい MCP サーバーとクライアントを見つける
- LangChain4J - モデル・コンテキスト・プロトコル(MCP)
オリジナルの投稿 A Java Geek on April 27, 2025
・Java Geek