⚡ Membangun aplikasi yang didukung LLM di Ruby ⚡
Untuk integrasi Rails yang mendalam, lihat: langchainrb_rails gem.
Tersedia untuk perjanjian konsultasi berbayar! Kirimi saya email.
Instal permata dan tambahkan ke Gemfile aplikasi dengan menjalankan:
bundle add langchainrb
Jika bundler tidak digunakan untuk mengelola dependensi, instal permata dengan menjalankan:
gem install langchainrb
Permata tambahan mungkin diperlukan. Mereka tidak disertakan secara default sehingga Anda hanya dapat menyertakan apa yang Anda perlukan.
require "langchain"
Modul Langchain::LLM
menyediakan antarmuka terpadu untuk berinteraksi dengan berbagai penyedia Model Bahasa Besar (LLM). Abstraksi ini memungkinkan Anda dengan mudah beralih di antara backend LLM yang berbeda tanpa mengubah kode aplikasi Anda.
Semua kelas LLM mewarisi dari Langchain::LLM::Base
dan menyediakan antarmuka yang konsisten untuk operasi umum:
Sebagian besar kelas LLM dapat diinisialisasi dengan kunci API dan opsi default opsional:
llm = Langchain :: LLM :: OpenAI . new (
api_key : ENV [ "OPENAI_API_KEY" ] ,
default_options : { temperature : 0.7 , chat_model : "gpt-4o" }
)
Gunakan metode embed
untuk menghasilkan penyematan untuk teks tertentu:
response = llm . embed ( text : "Hello, world!" )
embedding = response . embedding
embed()
text
: (Wajib) Teks masukan yang akan disematkan.model
: (Opsional) Nama model yang akan digunakan atau model penyematan default yang akan digunakan. Gunakan metode complete
untuk menghasilkan penyelesaian untuk prompt tertentu:
response = llm . complete ( prompt : "Once upon a time" )
completion = response . completion
complete()
prompt
: (Wajib) Perintah masukan untuk penyelesaian.max_tokens
: (Opsional) Jumlah maksimum token yang akan dihasilkan.temperature
: (Opsional) Mengontrol keacakan dalam pembuatan. Nilai yang lebih tinggi (misalnya 0,8) membuat keluaran lebih acak, sedangkan nilai yang lebih rendah (misalnya 0,2) membuatnya lebih deterministik.top_p
: (Opsional) Alternatif suhu, mengontrol keragaman token yang dihasilkan.n
: (Opsional) Jumlah penyelesaian yang akan dihasilkan untuk setiap prompt.stop
: (Opsional) Urutan di mana API akan berhenti menghasilkan token selanjutnya.presence_penalty
: (Opsional) Menghukum token baru berdasarkan keberadaannya dalam teks sejauh ini.frequency_penalty
: (Opsional) Menghukum token baru berdasarkan frekuensinya dalam teks sejauh ini. Gunakan metode chat
untuk menghasilkan penyelesaian obrolan:
messages = [
{ role : "system" , content : "You are a helpful assistant." } ,
{ role : "user" , content : "What's the weather like today?" }
# Google Gemini and Google VertexAI expect messages in a different format:
# { role: "user", parts: [{ text: "why is the sky blue?" }]}
]
response = llm . chat ( messages : messages )
chat_completion = response . chat_completion
chat()
messages
: (Wajib) Serangkaian objek pesan yang mewakili riwayat percakapan.model
: (Opsional) Model obrolan khusus yang akan digunakan.temperature
: (Opsional) Mengontrol keacakan dalam pembuatan.top_p
: (Opsional) Alternatif suhu, mengontrol keragaman token yang dihasilkan.n
: (Opsional) Jumlah pilihan penyelesaian obrolan yang akan dihasilkan.max_tokens
: (Opsional) Jumlah maksimum token yang akan dihasilkan dalam penyelesaian obrolan.stop
: (Opsional) Urutan di mana API akan berhenti menghasilkan token selanjutnya.presence_penalty
: (Opsional) Menghukum token baru berdasarkan keberadaannya dalam teks sejauh ini.frequency_penalty
: (Opsional) Menghukum token baru berdasarkan frekuensinya dalam teks sejauh ini.logit_bias
: (Opsional) Memodifikasi kemungkinan kemunculan token tertentu di penyelesaian.user
: (Opsional) Pengidentifikasi unik yang mewakili pengguna akhir Anda.tools
: (Opsional) Daftar alat yang mungkin dipanggil oleh model.tool_choice
: (Opsional) Mengontrol cara model memanggil fungsi. Berkat antarmuka terpadu, Anda dapat dengan mudah beralih di antara penyedia LLM yang berbeda dengan mengubah kelas yang Anda buat:
# Using Anthropic
anthropic_llm = Langchain :: LLM :: Anthropic . new ( api_key : ENV [ "ANTHROPIC_API_KEY" ] )
# Using Google Gemini
gemini_llm = Langchain :: LLM :: GoogleGemini . new ( api_key : ENV [ "GOOGLE_GEMINI_API_KEY" ] )
# Using OpenAI
openai_llm = Langchain :: LLM :: OpenAI . new ( api_key : ENV [ "OPENAI_API_KEY" ] )
Setiap metode LLM mengembalikan objek respon yang menyediakan antarmuka yang konsisten untuk mengakses hasil:
embedding
: Mengembalikan vektor penyematancompletion
: Mengembalikan penyelesaian teks yang dihasilkanchat_completion
: Mengembalikan penyelesaian obrolan yang dihasilkantool_calls
: Mengembalikan panggilan alat yang dilakukan oleh LLMprompt_tokens
: Mengembalikan jumlah token yang dimintacompletion_tokens
: Mengembalikan jumlah token yang telah selesaitotal_tokens
: Mengembalikan jumlah total token yang digunakan Catatan
Meskipun antarmuka inti konsisten di seluruh penyedia, beberapa LLM mungkin menawarkan fitur atau parameter tambahan. Konsultasikan dokumentasi untuk setiap kelas LLM untuk mempelajari tentang kemampuan dan opsi khusus penyedia.
Buat prompt dengan variabel input:
prompt = Langchain :: Prompt :: PromptTemplate . new ( template : "Tell me a {adjective} joke about {content}." , input_variables : [ "adjective" , "content" ] )
prompt . format ( adjective : "funny" , content : "chickens" ) # "Tell me a funny joke about chickens."
Membuat PromptTemplate hanya menggunakan prompt dan tanpa input_variables:
prompt = Langchain :: Prompt :: PromptTemplate . from_template ( "Tell me a funny joke about chickens." )
prompt . input_variables # []
prompt . format # "Tell me a funny joke about chickens."
Simpan templat prompt ke file JSON:
prompt . save ( file_path : "spec/fixtures/prompt/prompt_template.json" )
Memuat template prompt baru menggunakan file JSON:
prompt = Langchain :: Prompt . load_from_path ( file_path : "spec/fixtures/prompt/prompt_template.json" )
prompt . input_variables # ["adjective", "content"]
Buat prompt dengan beberapa contoh pengambilan gambar:
prompt = Langchain :: Prompt :: FewShotPromptTemplate . new (
prefix : "Write antonyms for the following words." ,
suffix : "Input: {adjective} n Output:" ,
example_prompt : Langchain :: Prompt :: PromptTemplate . new (
input_variables : [ "input" , "output" ] ,
template : "Input: {input} n Output: {output}"
) ,
examples : [
{ "input" : "happy" , "output" : "sad" } ,
{ "input" : "tall" , "output" : "short" }
] ,
input_variables : [ "adjective" ]
)
prompt . format ( adjective : "good" )
# Write antonyms for the following words.
#
# Input: happy
# Output: sad
#
# Input: tall
# Output: short
#
# Input: good
# Output:
Simpan templat prompt ke file JSON:
prompt . save ( file_path : "spec/fixtures/prompt/few_shot_prompt_template.json" )
Memuat template prompt baru menggunakan file JSON:
prompt = Langchain :: Prompt . load_from_path ( file_path : "spec/fixtures/prompt/few_shot_prompt_template.json" )
prompt . prefix # "Write antonyms for the following words."
Memuat template prompt baru menggunakan file YAML:
prompt = Langchain :: Prompt . load_from_path ( file_path : "spec/fixtures/prompt/prompt_template.yaml" )
prompt . input_variables #=> ["adjective", "content"]
Parsing respons teks LLM menjadi output terstruktur, seperti JSON.
Anda dapat menggunakan StructuredOutputParser
untuk menghasilkan perintah yang menginstruksikan LLM untuk memberikan respons JSON yang mengikuti skema JSON tertentu:
json_schema = {
type : "object" ,
properties : {
name : {
type : "string" ,
description : "Persons name"
} ,
age : {
type : "number" ,
description : "Persons age"
} ,
interests : {
type : "array" ,
items : {
type : "object" ,
properties : {
interest : {
type : "string" ,
description : "A topic of interest"
} ,
levelOfInterest : {
type : "number" ,
description : "A value between 0 and 100 of how interested the person is in this interest"
}
} ,
required : [ "interest" , "levelOfInterest" ] ,
additionalProperties : false
} ,
minItems : 1 ,
maxItems : 3 ,
description : "A list of the person's interests"
}
} ,
required : [ "name" , "age" , "interests" ] ,
additionalProperties : false
}
parser = Langchain :: OutputParsers :: StructuredOutputParser . from_json_schema ( json_schema )
prompt = Langchain :: Prompt :: PromptTemplate . new ( template : "Generate details of a fictional character. n {format_instructions} n Character description: {description}" , input_variables : [ "description" , "format_instructions" ] )
prompt_text = prompt . format ( description : "Korean chemistry student" , format_instructions : parser . get_format_instructions )
# Generate details of a fictional character.
# You must format your output as a JSON value that adheres to a given "JSON Schema" instance.
# ...
Kemudian parsing respons llm:
llm = Langchain :: LLM :: OpenAI . new ( api_key : ENV [ "OPENAI_API_KEY" ] )
llm_response = llm . chat ( messages : [ { role : "user" , content : prompt_text } ] ) . completion
parser . parse ( llm_response )
# {
# "name" => "Kim Ji-hyun",
# "age" => 22,
# "interests" => [
# {
# "interest" => "Organic Chemistry",
# "levelOfInterest" => 85
# },
# ...
# ]
# }
Jika parser gagal mengurai respons LLM, Anda dapat menggunakan OutputFixingParser
. Ia mengirimkan pesan kesalahan, keluaran sebelumnya, dan teks perintah asli ke LLM, meminta respons "diperbaiki":
begin
parser . parse ( llm_response )
rescue Langchain :: OutputParsers :: OutputParserException => e
fix_parser = Langchain :: OutputParsers :: OutputFixingParser . from_llm (
llm : llm ,
parser : parser
)
fix_parser . parse ( llm_response )
end
Alternatifnya, jika Anda tidak perlu menangani OutputParserException
, Anda dapat menyederhanakan kodenya:
# we already have the `OutputFixingParser`:
# parser = Langchain::OutputParsers::StructuredOutputParser.from_json_schema(json_schema)
fix_parser = Langchain :: OutputParsers :: OutputFixingParser . from_llm (
llm : llm ,
parser : parser
)
fix_parser . parse ( llm_response )
Lihat di sini untuk contoh konkritnya
RAG adalah metodologi yang membantu LLM menghasilkan informasi yang akurat dan terkini. Alur kerja RAG pada umumnya mengikuti 3 langkah di bawah ini:
Langchain.rb menyediakan antarmuka terpadu yang nyaman di atas basis data pencarian vektor yang didukung yang memudahkan untuk mengonfigurasi indeks Anda, menambahkan data, membuat kueri, dan mengambil darinya.
Basis data | Sumber terbuka | Penawaran awan |
---|---|---|
Kroma | ✅ | ✅ |
Epsila | ✅ | ✅ |
Hnswlib | ✅ | |
Milvus | ✅ | ✅ Awan Zilliz |
biji pinus | ✅ | |
vektor hal | ✅ | ✅ |
Qdrant | ✅ | ✅ |
lemah | ✅ | ✅ |
Pencarian elastis | ✅ | ✅ |
Pilih database pencarian vektor yang akan Anda gunakan, tambahkan ketergantungan permata dan buat instance klien:
gem "weaviate-ruby" , "~> 0.8.9"
Pilih dan buat instance penyedia LLM yang akan Anda gunakan untuk membuat penyematan
llm = Langchain :: LLM :: OpenAI . new ( api_key : ENV [ "OPENAI_API_KEY" ] )
client = Langchain :: Vectorsearch :: Weaviate . new (
url : ENV [ "WEAVIATE_URL" ] ,
api_key : ENV [ "WEAVIATE_API_KEY" ] ,
index_name : "Documents" ,
llm : llm
)
Anda dapat membuat instance database pencarian vektor lain yang didukung:
client = Langchain :: Vectorsearch :: Chroma . new ( ... ) # `gem "chroma-db", "~> 0.6.0"`
client = Langchain :: Vectorsearch :: Epsilla . new ( ... ) # `gem "epsilla-ruby", "~> 0.0.3"`
client = Langchain :: Vectorsearch :: Hnswlib . new ( ... ) # `gem "hnswlib", "~> 0.8.1"`
client = Langchain :: Vectorsearch :: Milvus . new ( ... ) # `gem "milvus", "~> 0.9.3"`
client = Langchain :: Vectorsearch :: Pinecone . new ( ... ) # `gem "pinecone", "~> 0.1.6"`
client = Langchain :: Vectorsearch :: Pgvector . new ( ... ) # `gem "pgvector", "~> 0.2"`
client = Langchain :: Vectorsearch :: Qdrant . new ( ... ) # `gem "qdrant-ruby", "~> 0.9.3"`
client = Langchain :: Vectorsearch :: Elasticsearch . new ( ... ) # `gem "elasticsearch", "~> 8.2.0"`
Buat skema default:
client . create_default_schema
Tambahkan data teks biasa ke database pencarian vektor Anda:
client . add_texts (
texts : [
"Begin by preheating your oven to 375°F (190°C). Prepare four boneless, skinless chicken breasts by cutting a pocket into the side of each breast, being careful not to cut all the way through. Season the chicken with salt and pepper to taste. In a large skillet, melt 2 tablespoons of unsalted butter over medium heat. Add 1 small diced onion and 2 minced garlic cloves, and cook until softened, about 3-4 minutes. Add 8 ounces of fresh spinach and cook until wilted, about 3 minutes. Remove the skillet from heat and let the mixture cool slightly." ,
"In a bowl, combine the spinach mixture with 4 ounces of softened cream cheese, 1/4 cup of grated Parmesan cheese, 1/4 cup of shredded mozzarella cheese, and 1/4 teaspoon of red pepper flakes. Mix until well combined. Stuff each chicken breast pocket with an equal amount of the spinach mixture. Seal the pocket with a toothpick if necessary. In the same skillet, heat 1 tablespoon of olive oil over medium-high heat. Add the stuffed chicken breasts and sear on each side for 3-4 minutes, or until golden brown."
]
)
Atau gunakan pengurai file untuk memuat, mengurai, dan mengindeks data ke dalam database Anda:
my_pdf = Langchain . root . join ( "path/to/my.pdf" )
my_text = Langchain . root . join ( "path/to/my.txt" )
my_docx = Langchain . root . join ( "path/to/my.docx" )
client . add_data ( paths : [ my_pdf , my_text , my_docx ] )
Format file yang didukung: docx, html, pdf, teks, json, jsonl, csv, xlsx, eml, pptx.
Ambil dokumen serupa berdasarkan string kueri yang diteruskan:
client . similarity_search (
query : ,
k : # number of results to be retrieved
)
Ambil dokumen serupa berdasarkan string kueri yang diteruskan melalui teknik HyDE:
client . similarity_search_with_hyde ( )
Ambil dokumen serupa berdasarkan penyematan yang diteruskan di:
client . similarity_search_by_vector (
embedding : ,
k : # number of results to be retrieved
)
Kueri berbasis RAG
client . ask ( question : "..." )
Langchain::Assistant
adalah kelas yang kuat dan fleksibel yang menggabungkan Model Bahasa Besar (LLM), alat, dan manajemen percakapan untuk menciptakan asisten yang cerdas dan interaktif. Ini dirancang untuk menangani percakapan yang kompleks, menjalankan alat, dan memberikan respons yang koheren berdasarkan konteks interaksi.
llm = Langchain :: LLM :: OpenAI . new ( api_key : ENV [ "OPENAI_API_KEY" ] )
assistant = Langchain :: Assistant . new (
llm : llm ,
instructions : "You're a helpful AI assistant" ,
tools : [ Langchain :: Tool :: NewsRetriever . new ( api_key : ENV [ "NEWS_API_KEY" ] ) ]
)
# Add a user message and run the assistant
assistant . add_message_and_run! ( content : "What's the latest news about AI?" )
# Supply an image to the assistant
assistant . add_message_and_run! (
content : "Show me a picture of a cat" ,
image_url : "https://upload.wikimedia.org/wikipedia/commons/thumb/d/dd/Gfp-wisconsin-madison-the-nature-boardwalk.jpg/2560px-Gfp-wisconsin-madison-the-nature-boardwalk.jpg"
)
# Access the conversation thread
messages = assistant . messages
# Run the assistant with automatic tool execution
assistant . run ( auto_tool_execution : true )
# If you want to stream the response, you can add a response handler
assistant = Langchain :: Assistant . new (
llm : llm ,
instructions : "You're a helpful AI assistant" ,
tools : [ Langchain :: Tool :: NewsRetriever . new ( api_key : ENV [ "NEWS_API_KEY" ] ) ]
) do | response_chunk |
# ...handle the response stream
# print(response_chunk.inspect)
end
assistant . add_message ( content : "Hello" )
assistant . run ( auto_tool_execution : true )
Perhatikan bahwa streaming saat ini tidak didukung untuk semua LLM.
llm
: Contoh LLM yang akan digunakan (wajib)tools
: Serangkaian contoh alat (opsional)instructions
: Instruksi sistem untuk asisten (opsional)tool_choice
: Menentukan bagaimana alat harus dipilih. Bawaan: "otomatis". Nama fungsi alat tertentu dapat diberikan. Ini akan memaksa Asisten untuk selalu menggunakan fungsi ini.parallel_tool_calls
: Apakah akan membuat beberapa panggilan alat paralel. Bawaan: benaradd_message_callback
: Fungsi panggilan balik (proc, lambda) yang dipanggil ketika ada pesan yang ditambahkan ke percakapan (opsional) assistant . add_message_callback = -> ( message ) { puts "New message: #{ message } " }
tool_execution_callback
: Fungsi panggilan balik (proc, lambda) yang dipanggil tepat sebelum alat dijalankan (opsional) assistant . tool_execution_callback = -> ( tool_call_id , tool_name , method_name , tool_arguments ) { puts "Executing tool_call_id: #{ tool_call_id } , tool_name: #{ tool_name } , method_name: #{ method_name } , tool_arguments: #{ tool_arguments } " }
add_message
: Menambahkan pesan pengguna ke array pesanrun!
: Memproses percakapan dan menghasilkan tanggapanadd_message_and_run!
: Menggabungkan penambahan pesan dan menjalankan asistensubmit_tool_output
: Mengirimkan output secara manual ke panggilan alatmessages
: Mengembalikan daftar pesan yang sedang berlangsungLangchain::Tool::Calculator
: Berguna untuk mengevaluasi ekspresi matematika. Membutuhkan gem "eqn"
.Langchain::Tool::Database
: Hubungkan database SQL Anda. Membutuhkan gem "sequel"
.Langchain::Tool::FileSystem
: Berinteraksi dengan sistem file (baca & tulis).Langchain::Tool::RubyCodeInterpreter
: Berguna untuk mengevaluasi kode Ruby yang dihasilkan. Membutuhkan gem "safe_ruby"
(Membutuhkan solusi yang lebih baik).Langchain::Tool::NewsRetriever
: Pembungkus NewsApi.org untuk mengambil artikel berita.Langchain::Tool::Tavily
: Pembungkus di sekitar Tavily AI.Langchain::Tool::Weather
: Memanggil Open Weather API untuk mengambil cuaca saat ini.Langchain::Tool::Wikipedia
: Memanggil API Wikipedia. Langchain::Assistant dapat dengan mudah diperluas menggunakan alat khusus dengan membuat kelas yang extend Langchain::ToolDefinition
dan mengimplementasikan metode yang diperlukan.
class MovieInfoTool
extend Langchain :: ToolDefinition
define_function :search_movie , description : "MovieInfoTool: Search for a movie by title" do
property :query , type : "string" , description : "The movie title to search for" , required : true
end
define_function :get_movie_details , description : "MovieInfoTool: Get detailed information about a specific movie" do
property :movie_id , type : "integer" , description : "The TMDb ID of the movie" , required : true
end
def initialize ( api_key : )
@api_key = api_key
end
def search_movie ( query : )
...
end
def get_movie_details ( movie_id : )
...
end
end
movie_tool = MovieInfoTool . new ( api_key : "..." )
assistant = Langchain :: Assistant . new (
llm : llm ,
instructions : "You're a helpful AI assistant that can provide movie information" ,
tools : [ movie_tool ]
)
assistant . add_message_and_run ( content : "Can you tell me about the movie 'Inception'?" )
# Check the response in the last message in the conversation
assistant . messages . last
Asisten mencakup penanganan kesalahan untuk input yang tidak valid, jenis LLM yang tidak didukung, dan kegagalan eksekusi alat. Ia menggunakan mesin negara untuk mengelola alur percakapan dan menangani berbagai skenario dengan baik.
Modul Evaluasi adalah kumpulan alat yang dapat digunakan untuk mengevaluasi dan melacak kinerja produk keluaran oleh LLM dan saluran RAG (Retrieval Augmented Generation) Anda.
Ragas membantu Anda mengevaluasi pipeline Retrieval Augmented Generation (RAG) Anda. Implementasinya didasarkan pada makalah ini dan repo Python asli. Ragas melacak 3 metrik berikut dan memberikan skor 0,0 - 1,0:
# We recommend using Langchain::LLM::OpenAI as your llm for Ragas
ragas = Langchain :: Evals :: Ragas :: Main . new ( llm : llm )
# The answer that the LLM generated
# The question (or the original prompt) that was asked
# The context that was retrieved (usually from a vectorsearch database)
ragas . score ( answer : "" , question : "" , context : "" )
# =>
# {
# ragas_score: 0.6601257446503674,
# answer_relevance_score: 0.9573145866787608,
# context_relevance_score: 0.6666666666666666,
# faithfulness_score: 0.5
# }
Contoh tambahan tersedia: /examples
Langchain.rb menggunakan mekanisme Ruby Logger standar dan defaultnya menggunakan nilai level
yang sama (saat ini Logger::DEBUG
).
Untuk menampilkan semua pesan log:
Langchain . logger . level = Logger :: DEBUG
Logger log ke STDOUT
secara default. Untuk mengonfigurasi tujuan log (mis. log ke file), lakukan:
Langchain . logger = Logger . new ( "path/to/file" , ** Langchain :: LOGGER_OPTIONS )
Jika Anda mengalami masalah saat memasang permata unicode
yang diperlukan oleh pragmatic_segmenter
, coba jalankan:
gem install unicode -- --with-cflags= " -Wno-incompatible-function-pointer-types "
git clone https://github.com/andreibondarev/langchainrb.git
cp .env.example .env
, lalu isi variabel lingkungan di .env
bundle exec rake
untuk memastikan bahwa tes lulus dan menjalankan standardrbbin/console
untuk memuat permata dalam sesi REPL. Jangan ragu untuk menambahkan contoh LLM, Alat, Agen, dll. Anda sendiri dan bereksperimenlah dengannya.gem install lefthook && lefthook install -f
Bergabunglah dengan kami di server Perselisihan Langchain.rb.
Laporan bug dan permintaan penarikan diterima di GitHub di https://github.com/andreibondarev/langchainrb.
Permata ini tersedia sebagai sumber terbuka berdasarkan ketentuan Lisensi MIT.