Bu eğitimde Dewy ve LangChain.js'yi kullanarak soru yanıtlayan bir CLI aracının nasıl oluşturulacağına odaklanıyoruz. Dewy, geliştiricilerin bilgileri verimli bir şekilde düzenlemesine ve almasına yardımcı olan açık kaynaklı bir bilgi tabanıdır. LangChain.js, büyük dil modellerinin (LLM'ler) uygulamalara entegrasyonunu kolaylaştıran bir çerçevedir. Dewy'nin bilgiyi yönetme yeteneklerini LangChain.js'nin LLM entegrasyonuyla birleştirerek, karmaşık sorguları kesin ve ilgili bilgilerle yanıtlayan araçlar oluşturabilirsiniz.
Bu kılavuz, ortamınızı kurma, belgeleri Dewy'ye yükleme ve depolanan verilere dayanarak soruları yanıtlamak için LangChain.js aracılığıyla bir LLM kullanma konusunda size yol gösterir. Projelerini gelişmiş soru yanıtlama işlevleriyle geliştirmek isteyen mühendisler için tasarlanmıştır.
Dewy, geliştiricilerin bilgileri depolama, düzenleme ve alma şeklini kolaylaştırmak için tasarlanmış bir OSS bilgi tabanıdır. Esnekliği ve kullanım kolaylığı, onu bilgi odaklı uygulamalar geliştirmeyi amaçlayan geliştiriciler için mükemmel bir seçim haline getiriyor.
LangChain.js ise geliştiricilerin LLM'leri uygulamalarına sorunsuz bir şekilde entegre etmelerini sağlayan güçlü bir çerçevedir. Geliştiriciler, Dewy'nin yapılandırılmış bilgi yönetimini LangChain.js'nin LLM yetenekleriyle birleştirerek, karmaşık sorguları anlayıp işleyebilen, kesin ve bağlamsal olarak anlamlı yanıtlar sunan gelişmiş soru yanıtlama sistemleri oluşturabilir.
Amacımız basit ama güçlü bir soru yanıtlayan CLI betiği oluşturmaktır. Bu komut dosyası, kullanıcıların belgeleri Dewy bilgi tabanına yüklemesine ve ardından LangChain.js aracılığıyla bir Yüksek Lisans kullanarak Dewy'de depolanan bilgilere dayanarak soruları yanıtlamasına olanak tanıyacak. Bu eğitim, ortamınızı kurmaktan CLI betiğini uygulamaya kadar olan süreç boyunca size rehberlik edecektir.
Basit bir soru yanıtlama uygulaması oluşturmak için LangChain'i nasıl kullanacağınızı ve uygulamanızın, sağladığınız belirli belgelere dayalı olarak soruları yanıtlamasına olanak tanıyarak Dewy'yi bir bilgi kaynağı olarak nasıl entegre edeceğinizi öğreneceksiniz.
Eğiticiye dalmadan önce aşağıdaki önkoşulların karşılandığından emin olun:
Devam etmek istiyorsanız bu örneğin son kodu Dewy deposunda mevcuttur.
Öncelikle TypeScript CLI projesi için bir dizin oluşturun ve dizine geçin.
mkdir dewy_qa cd dewy_qa
Dizin kurulumuyla TypeScript'i yükleyebilir ve projeyi başlatabilirsiniz:
npm init -y npm i typescript --save-dev npx tsc --init
Ortamınıza bağlı olarak TypeScript yapılandırmanızda bazı değişiklikler yapmanız gerekebilir. tsconfig.json
dosyanızın aşağıdaki gibi göründüğünden emin olun:
{ "compilerOptions": { "target": "ES6", "module": "CommonJS", "moduleResolution": "node", "declaration": true, "outDir": "./dist", "esModuleInterop": true, "strict": true, }
Artık CLI uygulamasını oluşturmaya hazırsınız. Kodun çok dağınık olmasını önlemek için, kodu aşağıdaki düzende çeşitli dizinler halinde düzenleyin
dewy_qa/ ├── commands/ │ └── ... ├── utils/ │ └── ... ├── index.ts ├── package.json └── tsconfig.ts
Her komut, commands
dizininde uygulanacak ve paylaşılan kod, utils
dizinine gidecek. CLI uygulamasının giriş noktası index.ts
dosyasıdır.
index.ts
basit bir "merhaba dünya" sürümüyle başlayın; bir sonraki bölümde doldurmaya başlayacaksınız
#!/usr/bin/env ts-node-script console.log("hello world");
Ortamın doğru kurulduğunu doğrulamak için aşağıdaki komutu çalıştırmayı deneyin; konsolda "merhaba dünya" yazdığını görmelisiniz:
npx ts-node index.ts
Bu çok uzun komutu her seferinde yazmak yerine, package.json
dosyasında komut için bir girdi oluşturalım. Bu, CLI'yi nasıl çağıracağımızı hatırlamamıza yardımcı olacak ve komut olarak kurulumu kolaylaştıracaktır:
{ ... "bin": { "dewy_qa": "./index.ts" } ... }
Artık betiğinizi npm exec dewy_qa
veya npm link
çalıştırabilir ve sadece dewy_qa
olarak çalıştırabilirsiniz.
Dewy istemcisini kurarak belgeleri yükleyin. İlk adım projeye bazı bağımlılıklar eklemektir. Bunlardan ilki, Dewy'nin istemci kütüphanesi olan dewy-ts
. İkincisi, bağımsız değişken ayrıştırma, alt komutlar ve daha fazlasını içeren bir CLI uygulaması oluşturmamıza yardımcı olacak commander
. Son olarak, chalk
istemleri daha renkli hale getirin.
npm install dewy-ts commander chalk
Daha sonra, yükleme komutunun mantığını uygulayın. Bunu commands/load.ts
adlı ayrı bir dosyada yapacaksınız. Bu dosya, bir URL ve bazı ek seçenekler bekleyen load
adlı bir işlevi uygular; bu, daha sonraki bir bölümde CLI ile bağlanacaktır.
Dewy, belge yüklemeyi son derece basit hale getirir; yalnızca istemciyi kurun ve yüklemek istediğiniz dosyanın URL'siyle addDocument
çağırın. Dewy, PDF'nin içeriğinin çıkarılmasıyla, bunları bir Yüksek Lisans'a göndermek için tam olarak doğru boyuttaki parçalara bölmekle ve anlamsal arama için dizine eklemekle ilgilenir.
import { Dewy } from 'dewy-ts'; import { success, error } from '../utils/colors'; export async function load(url: string, options: { collection: string, dewy_endpoint: string }): Promise<void> { console.log(success(`Loading ${url} into collection: ${options.collection}`)); try { const dewy = new Dewy({ BASE: options.dewy_endpoint }) const result = await dewy.kb.addDocument({ collection: options.collection, url }); console.log(success(`File loaded successfully`)); console.log(JSON.stringify(result, null, 2)); } catch (err: any) { console.error(error(`Failed to load file: ${err.message}`)); } }
Bazı işlevlerin ../utils/colors
adresinden içe aktarıldığını fark etmiş olabilirsiniz. Bu dosya, konsol çıktısını renklendirmek için bazı yardımcılar kurar; başka bir yerde kullanılabilmesi için utils
koyun:
import chalk from 'chalk'; export const success = (message: string) => chalk.green(message); export const info = (message: string) => chalk.blue(message); export const error = (message: string) => chalk.red(message);
Belgeleri Dewy'ye yükleme yeteneği sayesinde, soruları yanıtlamak için LLM'leri kullanmak üzere LangChain.js'yi entegre etmenin zamanı geldi. Bu adım, LangChain.js'nin Dewy bilgi tabanını sorgulamak ve yanıtları oluşturmak için bir Yüksek Lisans kullanarak sonuçları işlemek üzere kurulmasını içerir.
Başlamak için, OpenAI API'sini LLM olarak kullanmak için bazı ek paketler ( langchain
ve openai
yükleyin:
npm install dewy-langchain langchain @langchain/openai openai
Bu komut biraz uzun olduğundan, sonunda birleştirmeden önce birkaç parçasını inceleyeceğiz.
Kurulum için ilk şey Dewy (daha önce olduğu gibi) ve bir LLM'dir. Öncekinden bir fark, dewy
bir DewyRetriever
oluşturmak için kullanılmasıdır: bu, LangChain tarafından bir zincirin parçası olarak bilgi almak için kullanılan özel bir türdür. Bir dakika içinde av köpeğinin nasıl kullanıldığını göreceksiniz.
const model = new ChatOpenAI({ openAIApiKey: options.openai_api_key, }); const dewy = new Dewy({ BASE: options.dewy_endpoint }) const retriever = new DewyRetriever({ dewy, collection });
Bu, "zincir" oluşturulduğunda sağlanacak olan ek bağlam için yer tutucularla birlikte LLM'ye nasıl davranması gerektiği talimatını veren bir dize şablonudur. Bu durumda, Yüksek Lisans'a soruyu yanıtlaması talimatı verilir, ancak yalnızca kendisine sağlanan bilgileri kullanarak. Bu, modelin "halüsinasyon görme" veya makul ama yanlış bir cevap uydurma eğilimini azaltır. context
ve question
değerleri bir sonraki adımda verilmektedir:
const prompt = PromptTemplate.fromTemplate(`Answer the question based only on the following context: {context} Question: {question}`);
LangChain, LLM'nin ve diğer veri kaynaklarının nasıl sorgulanacağını kontrol eden davranış "zincirleri" oluşturarak çalışır. Bu örnekte, LangChain'in bazı orijinal arayüzlerinden daha esnek bir programlama deneyimi sağlayan LCEL kullanılmaktadır.
Bir LCEL zinciri oluşturmak için RunnableSequence
kullanın. Bu zincir, context
ve question
değerlerinin nasıl oluşturulacağını açıklar: bağlam, daha önce oluşturulan alıcı kullanılarak oluşturulur ve soru, adımın girdisinden geçilerek oluşturulur. Dewy'nin aldığı sonuçlar, formatDocumentsAsString
işlevine aktarılarak bir dize olarak biçimlendirilir.
Bu zincir şunları yapar:
DewyRetriever
kullanarak belgeleri alır ve bunları context
atar ve zincirin giriş değerini question
öğesine atar.context
ve question
değişkenlerini kullanarak bilgi istemi dizesini biçimlendirir. const chain = RunnableSequence.from([ { context: retriever.pipe(formatDocumentsAsString), question: new RunnablePassthrough(), }, prompt, model, new StringOutputParser(), ]);
Artık zincir oluşturulduğuna göre, onu yürütün ve sonuçları konsola aktarın. Göreceğiniz gibi question
, işlevi çağıran kişi tarafından sağlanan bir girdi argümanıdır.
Zinciri chain.streamLog()
kullanarak yürütmek, LLM'den döndürülen her yanıt parçasını görmenize olanak tanır. Akış işleyici döngüsü biraz çirkin, ancak yalnızca uygun akış sonuçlarını filtreliyor ve bunları STDOUT
yazıyor ( console.log
kullanıldığında her parçadan sonra yeni satırlar eklenirdi).
const stream = await chain.streamLog(question); // Write chunks of the response to STDOUT as they're received console.log("Answer:"); for await (const chunk of stream) { if (chunk.ops?.length > 0 && chunk.ops[0].op === "add") { const addOp = chunk.ops[0]; if ( addOp.path.startsWith("/logs/ChatOpenAI") && typeof addOp.value === "string" && addOp.value.length ) { process.stdout.write(addOp.value); } } }
Artık tüm parçaları gördüğünüze göre query
komutunu oluşturmaya hazırsınız. Bu, bazı ek içe aktarmalarla birlikte önceki load
komutuna benzer görünmelidir.
import { StringOutputParser } from "@langchain/core/output_parsers"; import { PromptTemplate } from "@langchain/core/prompts"; import { formatDocumentsAsString } from "langchain/util/document"; import { RunnablePassthrough, RunnableSequence } from "@langchain/core/runnables"; import { ChatOpenAI } from "@langchain/openai"; import { Dewy } from 'dewy-ts'; import { DewyRetriever } from 'dewy-langchain'; import { success, error } from '../utils/colors'; export async function query(question: string, options: { collection: string, dewy_endpoint: string, openai_api_key: string }): Promise<void> { console.log(success(`Querying ${options.collection} collection for: "${question}"`)); try { const model = new ChatOpenAI({ openAIApiKey: options.openai_api_key, }); const dewy = new Dewy({ BASE: options.dewy_endpoint }) const retriever = new DewyRetriever({ dewy, collection: options.collection }); const prompt = PromptTemplate.fromTemplate(`Answer the question based only on the following context: {context} Question: {question}`); const chain = RunnableSequence.from([ { context: retriever.pipe(formatDocumentsAsString), question: new RunnablePassthrough(), }, prompt, model, new StringOutputParser(), ]); const stream = await chain.streamLog(question); // Write chunks of the response to STDOUT as they're received console.log("Answer:"); for await (const chunk of stream) { if (chunk.ops?.length > 0 && chunk.ops[0].op === "add") { const addOp = chunk.ops[0]; if ( addOp.path.startsWith("/logs/ChatOpenAI") && typeof addOp.value === "string" && addOp.value.length ) { process.stdout.write(addOp.value); } } } } catch (err: any) { console.error(error(`Failed to query: ${err.message}`)); } }
Dewy ve LangChain.js entegre edildiğinde bir sonraki adım CLI arayüzünü oluşturmaktır. Belgeleri Dewy'ye yüklemeye ve LangChain.js kullanarak bilgi tabanını sorgulamaya yönelik komutları destekleyen, kullanıcı dostu bir komut satırı arayüzü oluşturmak için commander
gibi bir kitaplık kullanın.
İlk olarak, load
ve query
alt komutlarını oluşturmak için index.ts
dosyasını yeniden yazın. --collection
argümanı, belgenin hangi Dewy koleksiyonuna yüklenmesi gerektiğini belirler (Dewy, belgeleri dosya klasörlerine benzer şekilde farklı koleksiyonlar halinde düzenlemenize olanak tanır). --dewy-endpoint
bağımsız değişkeni, Dewy'ye nasıl bağlanacağınızı belirlemenizi sağlar; varsayılan olarak, 8000
bağlantı noktasında yerel olarak çalışan bir örneğin olduğu varsayılır. Son olarak --openai_api_key
argümanı (varsayılan olarak bir ortam değişkenidir) OpenAI API'sini yapılandırır:
#!/usr/bin/env ts-node-script import { Command } from 'commander'; import { load } from './commands/load'; import { query } from './commands/query'; const program = new Command(); program.name('dewy-qa').description('CLI tool for interacting with a knowledge base API').version('1.0.0'); const defaultOpenAIKey = process.env.OPENAI_API_KEY; program .command('load') .description("Load documents into Dewy from a URL") .option('--collection <collection>', 'Specify the collection name', 'main') .option('--dewy-endpoint <endpoint>', 'Specify the collection name', 'http://localhost:8000') .argument('<url>', 'URL to load into the knowledge base') .action(load); program .command('query') .description('Ask questions using an LLM and the loaded documents for answers') .option('--collection <collection>', 'Specify the collection name', 'main') .option('--dewy-endpoint <endpoint>', 'Specify the collection name', 'http://localhost:8000') .option('--openai-api-key <key>', 'Specify the collection name', defaultOpenAIKey) .argument('<question>', 'Question to ask the knowledge base') .action(query); program.parse(process.argv);
Tamam, her şey bitti; bu kadar kolay değil miydi? Komutu çalıştırarak deneyebilirsiniz:
dewy_qa load https://arxiv.org/pdf/2009.08553.pdf
Şöyle bir şey görmelisiniz
Loading https://arxiv.org/pdf/2009.08553.pdf into collection: main File loaded successfully { "id": 18, "collection": "main", "extracted_text": null, "url": "https://arxiv.org/pdf/2009.08553.pdf", "ingest_state": "pending", "ingest_error": null }
Büyük bir PDF'nin içeriğini çıkarmak bir veya iki dakika sürebilir, bu nedenle yeni bir belgeyi ilk yüklediğinizde sıklıkla "ingest_state": "pending"
görürsünüz.
Daha sonra bazı sorular sormayı deneyin:
dewy_qa query "tell me about RAG
Şöyle bir şey görmelisiniz
Querying main collection for: "tell me about RAG" Answer: Based on the given context, RAG refers to the RAG proteins, which are involved in DNA binding and V(D)J recombination. The RAG1 and RAG2 proteins work together to bind specific DNA sequences known as RSS (recombination signal sequences) and facilitate the cutting and rearrangement of DNA segments during the process of V(D)J recombination...
Bu kılavuzu takip ederek bilgiyi yönetmek için Dewy'yi ve soruları işlemek ve yanıtlar oluşturmak için LangChain.js'yi kullanan bir CLI'nin nasıl oluşturulacağını öğrendiniz. Bu araç, yapılandırılmış bir bilgi tabanını LLM'lerin analitik gücüyle birleştirmenin pratik uygulamasını göstererek geliştiricilerin daha akıllı ve duyarlı uygulamalar oluşturmasına olanak tanır.