Tahun lepas,Saya mula bercakap sedikitSekitarMelayu4jIa adalah projek yang berkembang pesat, dan saya ingin berkenalan dengan kemas kini. saya juga mahu memeriksa bagaimana untuk mengintegrasikan pelayan Protokol Konteks Model dalam LangChain4J.
Versi 1 Beta
Saya menulis post terakhir saya pada bulan November 2024 dan menggunakan versi terkini yang tersedia pada masa itu, v0.35. LangChain4J memulakan perjalanan ke arah 1.0 Disember lalu.
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 |
25 Disember 2024
daripada 35.0
22 Disember 2024
1.0.0-Alpha1 daripada
10 Februari 2025
1.0.0-beta 1 daripada
13 Disember 2025
1.0.0-beta2 daripada
Tanggal 12 April 2025
1.0.0-Beta3 daripada
LangChain4J mengikutSemarangPenyelenggara menggunakan peluang ini untuk memperkenalkan perubahan yang merosakkan.Dalam kes saya, saya terpaksa mengemas kini kod saya untuk mempertimbangkan perubahan API yang merosakkan.
v0.35 |
v1.0.0-beta3 |
---|---|
val s = Sinks.many() |
val s = Sinks.many() |
bermaksud s = banyak (
.Perkh (
.onBackpressureBuffer<String>()
chatBot.talk (m.sessionId, m.text)
.onNext(s::tryEmitSelanjutnya)
.onError(s::tryEmitError)
yang lengkap
Sijil Pengenalan (
Permulaan (
Pihak Berkuasa Pihak Berkuasa Pegawai (
s.asFlux().asFlow()
)
bermaksud s = banyak (
.Perkh (
.onBackpressureBuffer<String>()
chatBot.talk (m.sessionId, m.text)
.onPartialResponse(s::tryEmitNext)
.onError(s::tryEmitError)
.onKesimpulan Lengkap
Sijil Pengenalan (
Permulaan (
Pihak Berkuasa Pihak Berkuasa Pegawai (
s.asFlux().asFlow()
)
Projek Integrasi Reaktor
LangChain4J menawarkan integrasi Project Reactor; saya terlepas daripadanya dalam musings terdahulu saya.a lot.
Saya menggunakanAiServices
, jadi saya sebelum ini mendefinisikan antara muka untuk LangChain4J untuk dilaksanakan pada masa berjalan:
interface ChatBot {
fun talk(@MemoryId sessionId: String, @UserMessage message: String): TokenStream
}
Kita perlu menambah ketergantungan berikut:
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-reactor</artifactId>
<version>1.0.0-beta3</version>
</dependency>
Sekarang kita boleh menukar jenis pengembalian daripada aFlux<String>
dua aTokenStream
Berikut ialah tanda tangan yang dikemas kini:
interface ChatBot {
fun talk(@MemoryId sessionId: String, @UserMessage message: String): Flux<String>
}
Ia membolehkan penciptaansink
di atas tidak perlu. kita boleh menyederhanakan kod seperti berikut:
val flux = chatBot.talk(m.sessionId, m.text)
ServerResponse.ok().bodyAndAwait(flux.asFlow())
Ingat bahawa dua hari debugging boleh dengan mudah menjimatkan anda dua jam membaca dokumentasi!
Mengintegrasikan Model Konteks Protokol Server
Pada bahagian ini, saya ingin mengintegrasikan <abbr title="Model Context Protocol">MCP</abbr> dalam aplikasi LangChain4J saya.
Generasi Peningkatan Retrieval
Satu memerlukan banyak dan banyak sumber untuk melatih <abbr title="Large Language Model">LLM</abbr>: ia secara langsung diterjemahkan kepada masa dan wang. Untuk sebab ini, syarikat-syarikat mengehadkan latihan versi model baru. Kepentingan model berkurangan seiring dengan masa kerana maklumat menumpuk dan berubah, manakala pangkalan data LLM adalah tidak berubah.Selain itu, LLM dilatih pada data awam-dari sifatnya, manakala kebanyakan syarikat ingin menyiasat data peribadi mereka juga.
Retrieval-Augmented Generation adalah proses dua langkah. Dalam langkah pertama, alat ini menganalisa data, vektorisasi mengikut LLM, dan menyimpannya dalam pangkalan data vektor; dalam kedua, alat ini menggunakan pangkalan data sebagai data tambahan apabila menginterogasi LLM.
Protokol Konteks Model
Cara terkini untuk menangani sifat statik LLM adalah MCP.
MCP adalah protokol terbuka yang menyederhanakan bagaimana aplikasi menyediakan konteks kepada LLM. Pikirkan MCP sebagai port USB-C untuk aplikasi AI. Sama seperti USB-C menyediakan cara yang disetorkan untuk menyambungkan peranti anda kepada pelbagai peripheral dan aksesori, MCP menyediakan cara yang disetorkan untuk menyambungkan model AI kepada sumber data dan alat yang berbeza.
-- Mulakan dengan Protokol Konteks Model
MCP adalah protokol terbuka yang menyederhanakan bagaimana aplikasi menyediakan konteks kepada LLM. Pikirkan MCP sebagai port USB-C untuk aplikasi AI. Sama seperti USB-C menyediakan cara yang disetorkan untuk menyambungkan peranti anda kepada pelbagai peripheral dan aksesori, MCP menyediakan cara yang disetorkan untuk menyambungkan model AI kepada sumber data dan alat yang berbeza.
- - -Mulakan dengan Protokol Konteks Model
MCP mempunyai dua kelebihan berbanding RAG:
-
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 Menentukan2 Alternatif Pengangkutanuntuk komunikasi client-server :
- stdio: Klien melancarkan subproses, dan komunikasi berlaku di atas standard dalam dan standard keluar
- HTTP dengan peristiwa Server-Sent
Membina penyelesaian
Selepas teori di atas, kita kini bersedia untuk bahagian praktikal. ia bermula dengan memilih pelayan MCP.di siniIni merupakan permulaan yang baik, tetapi saya telah memilihPerkhidmatan GitHub MCP Serverkerana dokumen LangChain4J menyebutkannya.
GitHub MCP Server menawarkanStasiunpengangkutan.Ia bermakna kita perlu mendapatkan binari dan memulakan dari aplikasi.Ia cepat berbanding dengan pengangkutan HTTP, tetapi mengingat masa keseluruhan yang terdiri daripada panggilan HTTP kepada model dan masa pengiraan di pihaknya, ia tidak penting.Dari sudut pandang seni bina, saya lebih suka komponen khusus dengan prosesnya.
Selepas beberapa kajian, saya mendapati bahawaPerkhidmatan ProxyProjek. Ia membolehkan anda beralih antara daripada stdio kepada HTTP atau daripada HTTP kepada stdio. Ia juga boleh didapati sebagai imej Docker. Kami boleh menggabungkan kedua-dua pelayan dan proxy dengan berikut: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
- Muat turun fail
- mengekstrak
- Menghapuskan fail
- Buat Binar Eksekutif
Perlu diingat bahawa kita tidak boleh menentukanCMD
kerana binari hanya membolehkan mengkonfigurasi port dan host dengan parameter. untuk alasan ini, kita mesti menangguhkan perintah pada runtime, atau dalam kes saya, dalamdocker-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
- Kami memerlukan variabel persekitaran GITHUB_PERSONAL_ACCESS_TOKEN dengan token yang sah untuk mengesahkan pada GitHub
- Memindahkan semua variabel persekitaran kepada subproses
- Masukkan Port Pendengaran
- Mengikat kepada mana-mana IP
- Proxy "terhubung" kepada pelayan MCP stdio selepas dash
- Mulakan pelayan dengan semua opsyen diaktifkan
Imej ini akan memberikan/sse
Terdapat port 8080.
Mengkodkan penyelesaian
bahagian koding adalah yang paling mudah. kepala ke bawahDokumen LangChain4J pada MCPdan ikuti terus. dalam projek, ia diterjemahkan seperti berikut:
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)
}
}
- Saya menambah kelas ConfigurationProperty untuk parameter URL SSE
- Protokol MCP menyediakan cara untuk menghantar log kembali kepada klien
- Tidak perlu, tetapi ia membantu saya untuk memastikan klien disambungkan ke pelayan dan boleh senarai alat yang disediakan
- Plug dalam pembekal alat MCP yang dicipta di atas dalam AiServices
Pada titik ini, model harus menghantar permintaan yang sepadan dengan mana-mana alat yang didaftarkan kepada pelayan MCP.
curl -N -H 'Content-Type: application/json' localhost:8080 -d '{ "sessionId": "1", "text": "What are my top three most popular GitHub repos?" }'
Saya telah cuba beberapa kali, dan saya mendapat jawapan mengikut garis-garis ini:
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.
Model hanya mengabaikan alat-alat walaupun dokumen mengklaim sebaliknya.
Memperbaiki penyelesaian
Saya telah membaca dokumen LangChain4J beberapa kali, tetapi tanpa faedah. Saya telah cuba menggunakan OpenAI dan beberapa alat AI lain tanpa kejayaan. Kebanyakan jawapan mengesahkan ia harus bekerja daripada kotak. Sesetengah menyebut memanggil alat secara langsung, yang mengalahkan matlamat; satu menyebut bahawa Ollama tidak menyokong alat. Saya memeriksa blog Ollama: ia mengumumkan sokongan alat pada tahun 2024.
Arsitektur yang dipisahkan memperkenalkan lebih banyak bahagian yang bergerak. saya menduga sesuatu yang mungkin salah dalam rantaian panggilan keseluruhan. saya memadam proxy MCP, menambahgithub-mcp-server
langsung ke imej aplikasi, dan menukar kod daripada HTTP kepada stdio.
Saya hampir menyerah apabila saya memutuskan untuk kembali kepada akar.sampel daripada dokumen: ia hanya berfungsi!Ia adalah momen ha-ha saya.
Sampel menggunakan OpenAI, manakala saya menggunakan Ollama. saya cuba MCP dengan OpenAI, Mistral AI, dan Ollama. Hanya model OpenAI yang berfungsi dengan MCP.
curl -N -H 'Content-Type: application/json' localhost:8080 -d '{ "sessionId": "1", "text": "What are my top three most popular GitHub repos?" }'
Sekarang, OpenAI memaparkan permintaan dengan betul ke alat yang betul dan mengembalikan jawapan yang saya harapkan:
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.%
Oleh kerana kami menghantar token pengesahan kepada pelayan MCP, yang menghantarnya kepada API GitHub, yang terakhir tahu pengguna mana yang membuat panggilan.my reposSaya mengakui bahawa ia adalah kes penggunaan yang tidak biasa untuk aplikasi web biasa yang melayani beberapa pengguna, tetapi menggunakan satu token pengesahan masing-masing.
Soalan biasa yang lain,dan g.Cari repositori yang paling popular di GitHub, yang berkaitan dengan aplikasi web, kerana mereka tidak mempunyai konteks tersirat – pengguna.
Kesimpulan
Fokus utama post ini ialah integrasi pelayan MCP dalam aplikasi LangChain4J. Walaupun konfigurasi mudah berkat dokumentasi, terdapat beberapa amaran.
Pertama, bagaimana pelayan MCP cocok dalam seni bina anda masih bergantung kepada anda.mcp-proxy
Kemudian, LangChain4J kelihatan sebagai abstraksi yang bocor. Ia melakukan segala-galanya untuk menyediakan anda dengan lapisan abstraksi yang kuat, tetapi pelaksanaan di bawahnya melindungi anda daripada tidak sama.
Saya belajar tentang MCP di dunia sebenar, dan ia membuka beberapa pintu untuk idea projek.
Kode sumber lengkap untuk artikel ini boleh didapati diGitHub.
To go further:
- Mulakan dengan Protokol Konteks Model
- Cari Pelayan dan Pelanggan MCP yang Menakjubkan
- LangChain4J - Protokol Konteks Model (MCP)
Awalnya diterbitkan di A Java Geek pada 27 April, 2025
Tag: java geek