Tahun lalu, saya mulai menggali sedikit di sekitar langchain4j. Ini adalah proyek yang tumbuh cepat, dan saya ingin terbiasa dengan pembaruan. Saya juga ingin memeriksa cara mengintegrasikan server protokol konteks model di langchain4j.
Versi 1 beta
Saya menulis posting terakhir saya pada bulan November 2024 dan menggunakan versi terbaru yang tersedia pada saat itu, v0.35. Langchain4j memulai perjalanannya menuju 1.0 Desember lalu.
Tanggal |
Melepaskan |
---|---|
25 September 2024 |
0.35.0 |
22 Desember 2024 |
1.0.0-alpha1 |
10 Februari 2025 |
1.0.0-beta1 |
13 Maret 2025 |
1.0.0-beta2 |
12 April 2025 |
1.0.0-beta3 |
Langchain4j mengikuti SEMVER. Pemelihara menggunakan kesempatan itu untuk memperkenalkan perubahan yang melanggar. Dalam kasus saya, saya harus memperbarui kode saya untuk memperhitungkan perubahan API.
V0.35 |
v1.0.0-beta3 |
---|---|
val s = sinks.yyy () |
val s = sinks.yyy () |
Integrasi reaktor proyek
Langchain4j menawarkan integrasi reaktor proyek; Saya melewatkannya di renungan saya sebelumnya. Dengan Kotlin Coroutines, itu menyederhanakan kode banyak.
Saya menggunakan AiServices
jadi saya sebelumnya mendefinisikan antarmuka untuk diterapkan Langchain4j saat runtime:
interface ChatBot {
fun talk(@MemoryId sessionId: String, @UserMessage message: String): TokenStream
}
Kita harus menambahkan ketergantungan berikut:
dev.langchain4j
langchain4j-reactor
1.0.0-beta3
Kami sekarang dapat mengubah jenis pengembalian dari a Flux
ke a TokenStream
. Inilah tanda tangan yang diperbarui:
interface ChatBot {
fun talk(@MemoryId sessionId: String, @UserMessage message: String): Flux
}
Itu membuat penciptaan sink
di atas yang tidak perlu. Kita dapat menyederhanakan kode sebagai berikut:
val flux = chatBot.talk(m.sessionId, m.text)
ServerResponse.ok().bodyAndAwait(flux.asFlow())
Ingatlah bahwa dua hari debugging dapat dengan mudah menghemat dua jam membaca dokumentasi! Saya tidak melakukan yang terakhir.
Mengintegrasikan Server Protokol Konteks Model
Hingga saat ini, perubahan kami minimal. Di bagian ini, saya ingin mengintegrasikan MCP Dalam aplikasi Langchain4j saya.
Generasi Pengambilan-Agung
Seseorang membutuhkan banyak dan banyak sumber daya untuk melatih Llm: Ini secara langsung diterjemahkan ke dalam waktu dan uang. Untuk alasan ini, perusahaan membatasi pelatihan versi model baru. Relevansi model menurun dari waktu ke waktu karena informasi menghasilkan dan berubah, sedangkan database LLM tidak dapat diubah. Selain itu, LLM dilatih tentang data publik – dengan sifat, sementara sebagian besar perusahaan ingin menanyakan data pribadi mereka juga.
Pengambilan generasi augmented adalah cara tradisional untuk mengatasi batasan ini. Generasi Pengambilan-Agung adalah proses dua langkah. Pada langkah pertama, alat ini mem -parsing data, memvotokisasi sesuai dengan LLM, dan menyimpannya dalam database vektor; Pada yang kedua, alat ini menggunakan database sebagai data tambahan saat menanyakan LLM.
Protokol Konteks Model
Cara terbaru untuk menangani sifat statis LLMS adalah MCP.
MCP adalah protokol terbuka yang menstandarkan bagaimana aplikasi memberikan konteks kepada LLMS. Pikirkan MCP seperti port USB-C untuk aplikasi AI. Sama seperti USB-C menyediakan cara standar untuk menghubungkan perangkat Anda ke berbagai periferal dan aksesori, MCP menyediakan cara standar untuk menghubungkan model AI ke berbagai sumber data dan alat.
– Mulailah dengan protokol konteks model
MCP memiliki dua manfaat dari Rag:
-
Data yang diproses oleh kain dirancang untuk model. Jika seseorang ingin menggunakan model baru, seseorang harus mengeksekusi ulang fase parsing. MCP menstandarkan interaksi antara klien dan server, menjadikannya teknologi-independen.
-
Rag memungkinkan pembacaan data. MCP memungkinkan panggilan API apa pun untuk mengakses data secara dinamis atau menjalankan tindakanLai
MCP mendefinisikan dua alternatif transportasi untuk komunikasi klien-server:
- STDIO: Klien meluncurkan subproses, dan komunikasi terjadi lebih dari standar dan standar
- Http dengan acara server-sent
Mengarsipkan solusinya
Setelah teori di atas, kita sekarang siap untuk bagian langsung. Dimulai dengan memilih server MCP. Inilah titik awal yang bagus. Namun, saya memilih server MCP Github resmi karena dokumentasi Langchain4J menyebutkannya.
Server MCP GitHub menawarkan Stdio mengangkut. Itu berarti kita harus mendapatkan biner dan memulainya dari aplikasi. Ini cepat dibandingkan dengan transportasi HTTP, tetapi mengingat waktu keseluruhan yang terdiri dari panggilan HTTP ke model dan waktu komputasi di sisinya, itu tidak relevan. Dari sudut pandang arsitektur, saya lebih suka komponen khusus dengan prosesnya.
Setelah beberapa penelitian, saya menemukan proyek Proxy MCP. Ini memungkinkan Anda beralih di antara keduanya dari STDIO ke HTTP atau dari HTTP ke STDIO. Ini juga tersedia sebagai gambar Docker. Kami dapat menggabungkan server dan proxy dengan berikut ini 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
- Unduh arsipnya
- Ekstraknya
- Lepaskan arsipnya
- Jadikan biner yang dapat dieksekusi
Perhatikan bahwa kami tidak dapat mendefinisikan CMD
karena biner hanya memungkinkan mengkonfigurasi port dan host dengan parameter. Untuk alasan ini, kita harus menunda perintah saat runtime, atau dalam kasus saya, di 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
- Kami membutuhkan a
GITHUB_PERSONAL_ACCESS_TOKEN
Variabel lingkungan dengan token yang valid untuk mengotentikasi di github - Meneruskan semua variabel lingkungan ke subproses
- Atur port mendengarkan
- Berikatan dengan IP apapun
- Proxy “menghubungkan” ke server MCP STDIO setelah dasbor
- Jalankan server dengan semua opsi diaktifkan
Gambar akan memberikan /sse
Titik akhir di port 8080.
Mengkode solusinya
Bagian pengkodean adalah yang termudah. Pergilah ke dokumentasi Langchain4J di MCP dan ikuti. Dalam proyek, diterjemahkan sebagai sebagai berikut:
bean {
val transport = HttpMcpTransport.Builder()
.sseUrl(ref().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())
.chatMemoryProvider { MessageWindowChatMemory.withMaxMessages(40) }
.contentRetriever(EmbeddingStoreContentRetriever.from(ref>()))
.toolProvider(ref()) //4
.build()
POST("/")(PromptHandler(chatBot)::handle)
}
}
- Saya menambahkan a
ConfigurationProperty
kelas untuk parameterisasi URL SSE - Protokol MCP menyediakan cara untuk mengirim log kembali ke klien
- Tidak perlu, tetapi itu membantu saya memastikan klien terhubung ke server dan dapat mencantumkan alat yang disediakan
- Colokkan penyedia alat MCP yang dibuat di atas di
AiServices
Pada titik ini, model harus meneruskan permintaan yang cocok dengan salah satu alat terdaftar ke server MCP.
curl -N -H 'Content-Type: application/json' localhost:8080 -d '{ "sessionId": "1", "text": "What are my top three most popular GitHub repos?" }'
Saya mencoba beberapa kali, dan saya mendapat jawaban di sepanjang baris 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 meskipun dokumentasi mengklaim sebaliknya.
Memperbaiki solusinya
Saya membaca dokumentasi Langchain4J beberapa kali, tetapi tidak berhasil. Saya mencoba menggunakan Openai dan beberapa alat AI lainnya tanpa hasil. Sebagian besar jawaban dikonfirmasi harus bekerja di luar kotak. Beberapa disebutkan memanggil alat secara langsung, yang mengalahkan tujuan; Satu menyebutkan bahwa Ollama tidak mendukung alat. Saya memeriksa blog Ollama: mengumumkan dukungan alat pada tahun 2024. Saya terjebak selama hampir sehari, bertanya -tanya apa yang saya lakukan salah.
Arsitektur yang dipisahkan memperkenalkan lebih banyak bagian yang bergerak. Saya curiga ada yang salah di seluruh rantai panggilan. Saya menghapus proxy MCP, menambahkan github-mcp-server
langsung ke gambar aplikasi, dan mengubah kode dari HTTP ke STDIO. Itu tidak memperbaiki masalah.
Saya akan ditinggalkan ketika saya memutuskan untuk kembali ke akar. Saya menyalin sampel dari dokumentasi: itu hanya berhasil! Itu adalah momen ha-ha saya.
Sampel menggunakan Openai, saat saya menggunakan Ollama. Saya mencoba MCP dengan Openai, Mistral AI, dan Ollama. Hanya model OpenAI yang bekerja dengan MCP. Saya mengirim permintaan yang sama seperti di atas:
curl -N -H 'Content-Type: application/json' localhost:8080 -d '{ "sessionId": "1", "text": "What are my top three most popular GitHub repos?" }'
Sekarang, OpenAi dengan benar memetakan permintaan ke alat yang benar dan mengembalikan jawaban 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.%
Karena kami meneruskan token otentikasi ke server MCP, yang meneruskannya ke API GitHub, yang terakhir tahu pengguna mana yang melakukan panggilan. Oleh karena itu, dapat menafsirkan repo saya Bagian dalam kueri di atas. Saya akui bahwa ini adalah kasus penggunaan yang tidak biasa untuk aplikasi web reguler yang melayani banyak pengguna, tetapi menggunakan satu token otentikasi tunggal. Namun, sangat cocok dengan kasus penggunaan aplikasi desktop.
Pertanyaan reguler lainnya, misalnyaTemukan repositori paling populer di GitHub, relevan dengan aplikasi web, karena mereka tidak memiliki konteks implisit – pengguna.
Kesimpulan
Fokus utama dari posting ini adalah integrasi server MCP di aplikasi Langchain4j. Sementara konfigurasi langsung berkat dokumentasi, ada beberapa peringatan.
Pertama, bagaimana server MCP cocok dengan arsitektur Anda masih terserah Anda. Saya harus kreatif untuk membuatnya dipisahkan, menggunakan yang baik mcp-proxy
. Kemudian, langchain4j tampaknya menjadi abstraksi yang bocor. Itu membuat segala mungkin untuk memberi Anda lapisan abstraksi yang kuat, tetapi implementasi di bawahnya melindungi Anda dari tidak sama. Saya berharap dokumentasinya akan menyebutkannya, meskipun saya mengerti versi saat ini dalam beta.
Secara keseluruhan, itu adalah perjalanan yang menyenangkan. Saya belajar tentang MCP di dunia nyata, dan itu membuka beberapa pintu untuk ide -ide proyek.
Kode sumber lengkap untuk posting ini dapat ditemukan di GitHub.
Untuk melangkah lebih jauh:
Awalnya diterbitkan di java geek pada tanggal 27 April 2025