A tavalyi évben, Körül Ez egy gyorsan növekvő projekt, és meg akartam ismerkedni a frissítésekkel. Azt is meg akartam nézni, hogyan lehet integrálni egy Model Context Protocol szervert a LangChain4J-be. Elkezdtem egy kicsit Székesfehérvár4J 1 Béta verzió Az utolsó bejegyzésemet 2024 novemberében írtam, és az akkor elérhető legújabb verziót használtam, a v0.35. LangChain4J tavaly decemberben kezdte meg az 1.0 felé vezető utat. 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 szeptember 25, 2024 0 0 0 0 december 22, 2024 1 alfa1 alfa1 február 10, 2025 1 Béta1 Béta1 Március 13, 2025 1 Béta2 Béta2 Április 12, 2025 1.10 Béta3 LangChain4J előzetes A karbantartók kihasználták az alkalmat, hogy bevezessék a megszakító változásokat. Az én esetemben frissítenem kellett a kódomat az API megszakító változásainak figyelembevétele érdekében. Szemfény 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() ) Val s = szűk. sok() Egyedülálló ( .onBackpressureBuffer<String>() chatBot.talk(m.sessionId, m.text) - A beszélgetés .on Következő(s::tryEmitNext) .onHiba(s::nyomtatásHiba) A teljes Teljes körű( Kezdőlap » Hasonlóképpen, ha a hűtőszekrény ( Azaz a(z) a(z) a(z) ) Val s = szűk. sok() Egyedülálló ( .onBackpressureBuffer<String>() chatBot.talk(m.sessionId, m.text) - A beszélgetés KezdőlapHírekHírek(s::tryEmitNext) .onHiba(s::nyomtatásHiba) .onTeljes válasz { Teljes körű( Kezdőlap » Hasonlóképpen, ha a hűtőszekrény ( Azaz a(z) a(z) a(z) ) Reaktor integráció A LangChain4J a Project Reactor integrációját kínálja; az előző gondolataimban hiányoztam. . a lot Én használom , így korábban meghatároztam egy felületet a LangChain4J számára, hogy végrehajtsa a futási időben: AiServices interface ChatBot { fun talk(@MemoryId sessionId: String, @UserMessage message: String): TokenStream } Ehhez a következő függőséget kell kialakítanunk: <dependency> <groupId>dev.langchain4j</groupId> <artifactId>langchain4j-reactor</artifactId> <version>1.0.0-beta3</version> </dependency> Most már megváltoztathatjuk a visszatérés típusát a A két Íme a frissített aláírás: Flux<String> TokenStream interface ChatBot { fun talk(@MemoryId sessionId: String, @UserMessage message: String): Flux<String> } Ez teszi lehetővé a létrehozását a A fentiek nem szükségesek. a kódot a következőképpen egyszerűsíthetjük: sink val flux = chatBot.talk(m.sessionId, m.text) ServerResponse.ok().bodyAndAwait(flux.asFlow()) Ne feledje, hogy két napos hibakeresés könnyen megtakaríthatja a dokumentáció olvasásának két óráját! Kontextusprotokoll szerver integrálása Ebben a szakaszban szeretnék integrálni egy <abbr title="Model Context Protocol">MCP</abbr> a LangChain4J alkalmazásomban. Megnövekedett generáció Szükség van egy csomó erőforrásokat, hogy a vonat egy <abbr title="Large Language Model">LLM</abbr>: ez közvetlenül lefordítja az időt és pénzt. Emiatt a vállalatok korlátozzák a képzés az új modell változatait. A modell relevanciája csökken az idő múlásával, mint az információ felhalmozódik és változik, míg az LLM adatbázis változatlan. Ezen túlmenően, LLM-k képzett nyilvános adatok-a természet, míg a legtöbb vállalat azt akarja, hogy lekérdezzék a magán adatokat is. A Retrieval-Augmented Generation egy kétlépcsős folyamat.Az első lépésben az eszköz elemzi az adatokat, az LLM szerint vektorizálja őket, és egy vektor adatbázisban tárolja őket; a másodikban az eszköz az adatbázist további adatokként használja az LLM lekérdezésekor. Kontextus jegyzőkönyv Az LLM statikus jellegének legújabb kezelési módja az MCP. Az MCP egy nyílt protokoll, amely szabványosítja, hogy az alkalmazások hogyan nyújtanak kontextust az LLM-eknek. Gondolj az MCP-re, mint egy USB-C portra az AI-alkalmazásokhoz. Ahogy az USB-C szabványosított módot biztosít az eszközöknek a különböző perifériákhoz és tartozékokhoz való csatlakoztatására, az MCP szabványosított módot biztosít az AI modelleknek a különböző adatforrásokhoz és eszközökhöz való csatlakoztatására. -- Kezdje el a Model Context Protocol alkalmazást Az MCP egy nyílt protokoll, amely szabványosítja, hogy az alkalmazások hogyan nyújtanak kontextust az LLM-eknek. Gondolj az MCP-re, mint egy USB-C portra az AI-alkalmazásokhoz. Ahogy az USB-C szabványosított módot biztosít az eszközöknek a különböző perifériákhoz és tartozékokhoz való csatlakoztatására, az MCP szabványosított módot biztosít az AI modelleknek a különböző adatforrásokhoz és eszközökhöz való csatlakoztatására. - - - Indítsa el a Model Context Protocol alkalmazást Az MCP-nek két előnye van a RAG-hoz képest: 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 Az MCP meghatározása Ügyfél-szerver kommunikáció esetén: Két közlekedési alternatíva stdio: Az ügyfél elindítja az alfolyamatot, és a kommunikáció a standardon és a standardon túl történik. HTTP a Server-Sent eseményekkel A megoldás építése A fenti elmélet után most készen állunk a gyakorlati részre. Ez egy MCP szerver kiválasztásával kezdődik. Ez egy jó kiindulópont, de a Mert a LangChain4J dokumentáció említi. Itt az hivatalos GitHub MCP szerver A GitHub MCP szerver a Ez azt jelenti, hogy meg kell kapnunk a bináris és indítsa el az alkalmazás. Ez gyors, mint a HTTP szállítás, de figyelembe véve a teljes időt, amely magában foglalja a HTTP hívás a modell és a számítási idő az oldalán, ez irreleváns. Stúdió Néhány kutatás után kiderült, hogy a projekt. Lehetővé teszi, hogy stdio-ról HTTP-re vagy HTTP-ről stdio-ra váltson. Docker-képként is elérhető. : Proxy szolgáltatás 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 Letöltés archívum Kivonja azt Távolítsa el az archívumot A bináris végrehajthatóvá válik Megjegyzendő, hogy nem tudjuk meghatározni a mivel a bináris csak a port és a host paraméterekkel történő konfigurálását teszi lehetővé. ebből az okból el kell halasztanunk a parancsot a futási időben, vagy az én esetemben a : 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 Szükségünk van egy GITHUB_PERSONAL_ACCESS_TOKEN környezeti változóra érvényes tokennel a GitHub hitelesítéséhez Az összes környezeti változó átadása az alfolyamatba A meghallgatási port beállítása Csatlakozás bármely IP-hez A proxy a dash után "kapcsolja" a stdio MCP szervert Indítsa el a szervert az összes beállítással A kép biztosítja a A 8080-as porton érhető el. /sse A megoldás kódolása A kódolás a legegyszerűbb. lefelé a A projektben a következőképpen fordítják le: LangChain4J dokumentáció az MCP-ről 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 osztályt adtam hozzá az SSE URL paraméterezéséhez Az MCP protokoll lehetővé teszi a naplók visszaküldését a klienshez. Nem szükséges, de segített annak biztosításában, hogy a kliens csatlakozik a szerverhez, és felsorolja a rendelkezésre álló eszközöket. Csatlakoztassa a fentiekben létrehozott MCP-eszköz-szolgáltatót a AiServices Ebben a pillanatban a modellnek továbbítania kell a regisztrált eszközök bármelyikének megfelelő kérést az MCP-kiszolgálóra. curl -N -H 'Content-Type: application/json' localhost:8080 -d '{ "sessionId": "1", "text": "What are my top three most popular GitHub repos?" }' Többször megpróbáltam, és a válaszokat ezeken a vonalakon kaptam: 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. A modell egyszerűen figyelmen kívül hagyta az eszközöket, annak ellenére, hogy a dokumentáció az ellenkezőjét állítja. A megoldás rögzítése Elolvastam a LangChain4J dokumentációt néhányszor, de haszontalanul. Megpróbáltam használni az OpenAI-t és egy maroknyi más AI-eszközt sikertelenül. A legtöbb válasz megerősítette, hogy ki kell dolgoznia a dobozból. Néhányan megemlítették, hogy közvetlenül hívják az eszközt, ami legyőzi a célt; egyik megemlítette, hogy Ollama nem támogatja az eszközöket. Ellenőriztem az Ollama blogot: bejelentette az eszközök támogatását 2024-ben. Az elkülönített architektúra több mozgó darabot vezet be. gyanítottam, hogy valami rossz lehet az egész hívási láncban. eltávolítottam az MCP proxy-t, hozzáadtam a közvetlenül az alkalmazás képre, és a kódot HTTP-ről stdio-ra változtatta. github-mcp-server Majdnem feladtam, amikor úgy döntöttem, hogy visszatérek a gyökerekhez. Ez volt az én ha-ha pillanatom. Példa a dokumentációból A minta OpenAI-t használ, miközben Ollama-t használtam. megpróbáltam MCP-t OpenAI-val, Mistral AI-val és Ollamával. Csak az OpenAI modell működik az MCP-vel. ugyanazt a kérést küldtem el, mint fent: curl -N -H 'Content-Type: application/json' localhost:8080 -d '{ "sessionId": "1", "text": "What are my top three most popular GitHub repos?" }' Most az OpenAI helyesen ábrázolja a kérést a megfelelő eszközre, és visszaadja a várt választ: 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.% Mivel egy hitelesítési tokent továbbítunk az MCP szerverre, amely átadja azt a GitHub API-nak, az utóbbi tudja, hogy melyik felhasználó teszi a hívást. Bevallom, hogy ez egy szokatlan használati eset a rendszeres webes alkalmazások számára, amelyek több felhasználót szolgálnak ki, de mindegyikben egyetlen hitelesítési tokent használnak. my repos Egyéb gyakori kérdések, A legnépszerűbb tárhelyek a GitHub-on relevánsak a webes alkalmazásokhoz, mivel nincsenek implicit kontextusuk – a felhasználó. Az e.g következtetés Ennek a bejegyzésnek a középpontjában az MCP-kiszolgáló integrációja áll egy LangChain4J alkalmazásban.A konfiguráció a dokumentációnak köszönhetően egyszerű, de van néhány figyelmeztetés. Először is, az, hogy az MCP szerver hogyan illeszkedik az architektúrájába, még mindig rajtad múlik. Ezután a LangChain4J úgy tűnik, hogy egy szivárgó absztrakció. Mindent megtesz, hogy erős absztrakciós réteget biztosítson Önnek, de az alatta lévő megvalósítások nem egyenlőek. mcp-proxy Megtanultam az MCP-ről a valós világban, és ez elég sok ajtót nyitott a projekt ötletekre. A cikk teljes forráskódja megtalálható a . GitHub szolgáltatás To go further: Indítsa el a Model Context Protocol alkalmazást Keressen remek MCP szervereket és klienseket LangChain4J - Modellező kontextus protokoll (MCP) Eredetileg közzétett A Java Geek április 27, 2025 Egy Java Geek