۲۹ شهریور ۱۴۰۳

Techboy

اخبار و اطلاعات روز تکنولوژی

هوش مصنوعی مولد با LangChain، RStudio، و فقط کافی پایتون

LangChain یکی از داغ‌ترین پلتفرم‌ها برای کار با LLM و هوش مصنوعی مولد است – اما معمولاً فقط برای کاربران پایتون و جاوا اسکریپت است. در اینجا آمده است که چگونه کاربران R می توانند از آن دور شوند.

LangChain یکی از داغ‌ترین پلتفرم‌ها برای کار با LLM و هوش مصنوعی مولد است – اما معمولاً فقط برای کاربران پایتون و جاوا اسکریپت است. در اینجا آمده است که چگونه کاربران R می توانند از آن دور شوند.

LangChain یکی از داغ‌ترین پلت‌فرم‌های توسعه برای ایجاد برنامه‌هایی است که از هوش مصنوعی مولد استفاده می‌کنند — اما فقط برای Python و JavaScript در دسترس است. اگر یک برنامه نویس R هستید و می خواهید از LangChain استفاده کنید، چه کاری باید انجام دهید؟

خوشبختانه، شما می توانید بسیاری از کارهای مفید را در LangChain با کدهای بسیار ابتدایی پایتون انجام دهید. و، به لطف بسته reticulate R، کاربران R و RStudio می‌توانند پایتون را در محیطی که راحت هستند بنویسند و اجرا کنند – از جمله انتقال اشیا و داده‌ها بین پایتون و R.

در این آموزش LangChain، نحوه کار با Python و R برای دسترسی به APIهای LangChain و OpenAI را به شما نشان خواهم داد. این به شما امکان می‌دهد از مدل زبان بزرگ (LLM)—فناوری پشت ChatGPT— برای پرس و جو از اسناد PDF 300 صفحه‌ای ggplot2 استفاده کنید. اولین پرس و جوی نمونه ما: “چگونه متن را روی محور x یک نمودار بچرخانید؟”

در اینجا نحوه شکست روند، مرحله به مرحله آمده است:

  1. اگر قبلاً این کار را نکرده اید، سیستم خود را طوری تنظیم کنید که پایتون و شبکه را اجرا کند.
  2. فایل اسناد PDF ggplot2 را به عنوان یک شیء LangChain با متن ساده وارد کنید.
  3. متن را به قطعات کوچک‌تری تقسیم کنید که توسط یک مدل زبان بزرگ قابل خواندن باشد، زیرا این مدل‌ها محدودیت‌هایی برای خواندن همزمان دارند. ۳۰۰ صفحه متن از محدودیت های OpenAI فراتر خواهد رفت.
  4. از یک LLM برای ایجاد “جاسازی” برای هر تکه متن و ذخیره همه آنها در یک پایگاه داده استفاده کنید. تعبیه رشته ای از اعداد است که معنای معنایی متن را در فضای چند بعدی نشان می دهد.
  5. یک جاسازی برای سوال کاربر ایجاد کنید، سپس جاسازی سوال را با تمام سوالات موجود از متن مقایسه کنید. مرتبط ترین قطعات متن را پیدا و بازیابی کنید.
  6. فقط آن بخش‌های مرتبط از متن را به یک LLM مانند GPT-3.5 بدهید و از آن بخواهید که پاسخی ایجاد کند.

اگر می‌خواهید از مثال‌ها پیروی کنید و از OpenAI API استفاده کنید، به یک کلید API نیاز دارید. می‌توانید در platform.openai.com ثبت‌نام کنید. اگر ترجیح می دهید از مدل دیگری استفاده کنید، LangChain دارای اجزایی برای ایجاد زنجیره برای بسیاری از LLM ها، نه تنها OpenAI است، بنابراین شما در یک ارائه دهنده LLM قفل نیستید.

LangChain دارای اجزایی است که می‌تواند بیشتر این مراحل را به راحتی انجام دهد، به خصوص اگر از پیش‌فرض‌های آن راضی باشید. به همین دلیل است که بسیار محبوب شده است.

بیایید شروع کنیم.

مرحله ۱: سیستم خود را برای اجرای Python در RStudio تنظیم کنید

اگر قبلا پایتون و شبکه را اجرا کرده اید، می توانید به مرحله بعدی بروید. در غیر این صورت، بیایید مطمئن شویم که نسخه اخیر پایتون را در سیستم خود دارید. راه های زیادی برای نصب Python وجود دارد، اما به سادگی دانلود از python.org برای من کارساز بود. سپس بسته reticulate R را به روش معمول با install.packages("reticulate") نصب کنید.

اگر پایتون را نصب کرده اید اما reticulate نمی تواند آن را پیدا کند، می توانید از دستور use_python("/path/to/your/python") استفاده کنید. .

استفاده از محیط‌های مجازی که به شما امکان می‌دهد نسخه‌های بسته‌ای را نصب کنید که با الزامات پروژه‌های دیگر در جای دیگر سیستم شما در تضاد نباشد، تمرین پایتون خوبی است. در اینجا نحوه ایجاد یک محیط مجازی پایتون جدید و استفاده از کد R برای نصب بسته های مورد نیاز آمده است:


library(reticulate)
virtualenv_create(envname = "langchain_env", packages = c( "langchain", "openai", "pypdf", "bs4", "python-dotenv", "chromadb", "tiktoken")) # Only do this once

توجه داشته باشید که می‌توانید محیط خود را هر چه دوست دارید نامگذاری کنید. اگر بعد از ایجاد محیط نیاز به نصب بسته‌ها دارید، از py_install() استفاده کنید، مانند:


py_install(packages = c( "langchain", "openai", "pypdf", "bs4", "python-dotenv", "chromadb", "tiktoken"), envname = "langchain_env")

همانطور که در R، شما فقط باید یک بار بسته ها را نصب کنید، نه هر بار که نیاز به استفاده از محیط دارید. همچنین فراموش نکنید که محیط مجازی خود را با

فعال کنید


use_virtualenv("langchain_env")

این کار را هر بار که به پروژه باز می گردید و قبل از شروع اجرای کد پایتون انجام خواهید داد.

می توانید آزمایش کنید که آیا محیط پایتون شما با موارد اجباری کار می کند


reticulate::py_run_string('
print("Hello, world!") ')

در صورت تمایل می توانید کلید OpenAI API خود را با یک متغیر پایتون تنظیم کنید. از آنجایی که من قبلاً آن را در یک متغیر محیطی R دارم، معمولاً کلید OpenAI API را با استفاده از R تنظیم می‌کنم. می‌توانید هر متغیر R را در قالبی سازگار با پایتون با تابع r_to_py()، از جمله متغیرهای محیطی ذخیره کنید. :


api_key_for_py <- r_to_py(Sys.getenv("OPENAI_API_KEY"))

که متغیر محیطی OPENAI_API_KEY را می گیرد، مطمئن می شود که سازگار با پایتون است، و آن را در یک متغیر جدید ذخیره می کند: api_key_for_py (باز هم، نام می تواند هر چیزی باشد).< /p>

بالاخره، ما آماده کدنویسی هستیم!

مرحله ۲: فایل PDF را دانلود و وارد کنید

من می‌خواهم یک فهرست فرعی docs جدید از فهرست اصلی پروژه‌ام ایجاد کنم و از R برای دانلود فایل در آنجا استفاده کنم.


# Create the directory if it doesn't exist
if(!(dir.exists("docs"))) {
  dir.create("docs")
}

# Download the file
download.file("https://cran.r-project.org/web/packages/ggplot2/ggplot2.pdf", destfile = "docs/ggplot2.pdf", mode = "wb")

سپس کد پایتون برای وارد کردن فایل به عنوان یک شی سند LangChain که شامل محتوا و ابرداده است می آید. من یک فایل اسکریپت پایتون جدید به نام prep_docs.py برای این کار ایجاد خواهم کرد. می‌توانم با استفاده از تابع py_run_string() به اجرای کد پایتون درست در اسکریپت R ادامه دهم، همانطور که در بالا انجام دادم. با این حال، اگر روی یک کار بزرگ‌تر کار می‌کنید، ایده‌آل نیست، زیرا چیزهایی مانند تکمیل کد را از دست می‌دهید.

نقطه حیاتی برای مبتدیان پایتون: از نام یکسانی برای فایل اسکریپت خود به عنوان یک ماژول پایتون که بارگیری می کنید استفاده نکنید! به عبارت دیگر، در حالی که فایل لازم نیست چنین باشد. prep_docs.py نامیده می شود، اگر بسته langchain را وارد می کنید، مثلاً langchain.py را نامگذاری نکنید! آنها درگیر خواهند شد. این یک مشکل در R.

نیست

این قسمت اول فایل prep_docs.py جدید من است:


# If running from RStudio, remember to first run in R:
# library(reticulate)
# use_virtualenv("the_virtual_environment_you_set_up")
# api_key_py <- r_to_py(Sys.getenv("OPENAI_API_KEY"))

from langchain.document_loaders import PyPDFLoader
my_loader = PyPDFLoader('docs/ggplot2.pdf')
# print(type (my_loader))
all_pages = my_loader.load()
# print(type(all_pages)) 
print( len(all_pages) )

این کد ابتدا بارکننده سند PDF PyPDFLoader را وارد می‌کند. در مرحله بعد، نمونه ای از کلاس بارگذار PDF ایجاد می کند. سپس، لودر و روش load آن را اجرا می کند و نتایج را در متغیری به نام all_pages ذخیره می کند. آن شی یک لیست پایتون است.

من برخی از خطوط نظر داده شده را اضافه کرده ام که در صورت تمایل به دیدن انواع اشیا چاپ می شوند. خط آخر طول لیست را چاپ می کند، که در این مورد ۳۰۴ است، یک عدد برای هر صفحه در PDF.

برای اجرای یک اسکریپت کامل Python می توانید روی دکمه source در RStudio کلیک کنید. یا، برخی از خطوط کد را برجسته کنید و فقط آنها را اجرا کنید، درست مانند یک اسکریپت R. کد پایتون هنگام اجرا کمی متفاوت از کد R به نظر می رسد، زیرا یک جلسه REPL تعاملی پایتون را درست در کنسول R شما باز می کند. به شما دستور داده می شود که exit یا quit (بدون پرانتز) را تایپ کنید تا خارج شوید و پس از پایان کار به کنسول R معمولی خود بازگردید.

python in r screenshot

شما می توانید all_pages شی پایتون را در R با استفاده از شی py reticulate بررسی کنید. کد R زیر آن شی all_pages پایتون را در یک متغیر R با نام all_pages_in_r ذخیره می‌کند (شما می‌توانید آن را هر چیزی که دوست دارید نام ببرید). سپس می توانید مانند هر شی R دیگر با شی کار کنید. در این مورد، این یک لیست است.


all_pages_in_r <- py$all_pages
# Examples:
all_pages_in_r[[1]]$metadata # See metadata in the first item
nchar(all_pages_in_r[[100]]$page_content) # Count number of characters in the 100th item

ادغام های LangChain

اگر در حال حاضر روش مورد علاقه ای برای تبدیل فایل های PDF به متن قابل خواندن ندارید، PyPDFLoader LangChain می تواند برای سایر پروژه های غیر هوش مصنوعی مفید باشد. و، LangChain بیش از ۱۰۰ بارکننده سند دیگر برای فرمت‌هایی از جمله PowerPoint، Word، صفحات وب، YouTube، epub، Evernote و Notion دارد. می‌توانید برخی از قالب‌های فایل و بارکننده‌های سند یکپارچه‌سازی را در مرکز ادغام‌های LangChain مشاهده کنید.

مرحله ۳: سند را به قطعات تقسیم کنید

LangChain دارای چندین ترانسفورماتور برای تقسیم اسناد به تکه‌ها، از جمله تقسیم بر اساس کاراکترها، نشانه‌ها، و هدرهای علامت‌گذاری برای اسناد علامت‌گذاری است. یکی از پیش‌فرض‌های پیشنهادی RecursiveCharacterTextSplitter است که “به صورت بازگشتی سعی می‌کند بر اساس نویسه‌های مختلف تقسیم شود تا یکی را پیدا کند که کار می‌کند.” یکی دیگر از گزینه های محبوب CharacterTextSplitter است که به گونه ای طراحی شده است که کاربر پارامترهای خود را تنظیم کند.

شما می‌توانید حداکثر اندازه تکه متن این تقسیم‌کننده را تنظیم کنید، این که آیا باید با نویسه‌ها یا نشانه‌های LLM شمارش شود (توکن‌ها معمولاً یک تا چهار کاراکتر هستند)، و اینکه چقدر تکه‌ها باید همپوشانی داشته باشند. من تا زمانی که شروع به استفاده از LangChain نکردم به لزوم همپوشانی تکه‌های متن فکر نکرده بودم، اما منطقی است مگر اینکه بتوانید با قطعات منطقی مانند فصل‌ها یا بخش‌هایی که با هدر جدا شده‌اند، جداسازی کنید. در غیر این صورت، متن شما ممکن است در وسط جمله تقسیم شود، و یک قطعه اطلاعات مهم ممکن است بین دو قسمت تقسیم شود، بدون اینکه معنی کامل در هیچ کدام واضح باشد.

همچنین می‌توانید جداکننده‌هایی را که می‌خواهید وقتی متن شما را تقسیم می‌کند، اولویت‌بندی کند، انتخاب کنید. پیش‌فرض CharacterTextSplitter این است که ابتدا روی دو خط جدید (\n\n) تقسیم می‌شود، سپس یک خط جدید، یک فاصله، و در نهایت هیچ جداکننده‌ای وجود ندارد. p>

کد زیر کلید OpenAI API من را از متغیر R api_key_for_py با استفاده از شئ r reticulate داخل پایتون وارد می‌کند. همچنین بسته openai پایتون و تقسیم‌کننده نویسه‌های بازگشتی LangChain را بارگیری می‌کند، نمونه‌ای از کلاس RecursiveCharacterTextSplitter ایجاد می‌کند و روش‌های split_documents() آن نمونه را اجرا می‌کند. در قسمت‌های all_pages.


import openai
openai.api_key = r.api_key_for_py  
from langchain.text_splitter import RecursiveCharacterTextSplitter
my_doc_splitter_recursive = RecursiveCharacterTextSplitter()
my_split_docs = my_doc_splitter_recursive.split_documents(all_pages)

دوباره، می‌توانید این نتایج را با کد R مانند:

به R ارسال کنید


my_split_docs <- py$my_split_docs

آیا می‌پرسید حداکثر تعداد کاراکترها در یک تکه چقدر است؟ من می توانم این را در R با یک تابع سفارشی کوچک برای لیست بررسی کنم:


get_characters <- function(the_chunk) {
x <- nchar(the_chunk$page_content)
return(x)
}

purrr::map_int(my_split_docs, get_characters) |>
max()

که ۳۹۸۵ نویسه ایجاد کرد، بنابراین به نظر می‌رسد که حداکثر قطعه پیش‌فرض ۴۰۰۰ کاراکتر باشد.

اگر تکه‌های متن کوچک‌تری می‌خواستم، ابتدا CharacterTextSplitter را امتحان می‌کردم و به صورت دستی chunk_size را روی کمتر از ۴۰۰۰ تنظیم می‌کردم، مانند


chunk_size = 1000
chunk_overlap = 150
from langchain.text_splitter import CharacterTextSplitter
c_splitter = CharacterTextSplitter(chunk_size=chunk_size, chunk_overlap=chunk_overlap, separator=" ")
c_split_docs = c_splitter.split_documents(all_pages)
print(len(c_split_docs)) # To see in Python how many chunks there are now

من می توانم نتایج را در R و همچنین Python بررسی کنم:


c_split_docs <- py$c_split_docs
length(c_split_docs)

این کد ۶۹۵ تکه با حداکثر اندازه ۱۰۰۰ تولید کرد.

هزینه آن چقدر است؟

قبل از ادامه دادن، می‌خواهم بدانم که آیا ایجاد جاسازی‌ها برای همه آن تکه‌ها بسیار گران است یا خیر. من با ۳۰۶ آیتم تقسیم بازگشتی پیش فرض شروع می کنم. من می‌توانم تعداد کل کاراکترها را در آن تکه‌ها روی شی R با استفاده از:

محاسبه کنم


purrr::map_int(my_split_docs, get_characters) |>
  sum()

پاسخ ۵۱۳۵۰۶ است. تخمین محافظه کارانه دو کاراکتر در هر نشانه، به حدود ۲۰۰۰۰۰ می رسد.

اگر می‌خواهید دقیق‌تر باشید، بسته TheOpenAIR R یک تابع count_tokens() دارد (حتماً آن را نصب کنید و برای استفاده از کد R زیر purrr کنید):


purrr::map_int(my_split_docs, ~ TheOpenAIR::count_tokens(.x$page_content)) |> 
   sum()

این کد ۱۲۶۳۴۳ توکن را نشان می دهد.

هزینه آن چقدر است؟ مدل OpenAI که برای ایجاد جاسازی طراحی شده است ada-2 است. از زمان نوشتن این مقاله ada-2 0.0001 دلار برای ۱ هزار توکن یا حدود ۱.۳ سنت برای ۱۲۶۰۰۰ قیمت دارد. . این در حد بودجه است!

مرحله ۴: ایجاد جاسازی‌ها

LangChain دارای اجزای از پیش ساخته شده برای ایجاد جاسازی از تکه‌های متن و ذخیره آنها است. برای ذخیره سازی، از یکی از ساده ترین گزینه های موجود در LangChain استفاده می کنم: Chroma، یک پایگاه داده جاسازی منبع باز که می توانید به صورت محلی از آن استفاده کنید.

ابتدا، من یک زیر شاخه از دایرکتوری docs خود را با کد R فقط برای پایگاه داده ایجاد می کنم، زیرا پیشنهاد می شود چیزی جز پایگاه داده شما در دایرکتوری Chroma نباشد. این کد R است:


if(!dir.exists("docs/chroma_db")) {
  dir.create("docs/chromaba_db")
}

در زیر تعدادی کد پایتون برای ایجاد جاسازی ها با استفاده از OpenAIEmbeddings LangChain آورده شده است. که در حال حاضر به صورت پیش‌فرض روی مدل OpenAI ada-2 است، بنابراین نیازی به تعیین آن ندارید. اگرچه LangChain از تعدادی LLM دیگر با کلاس Embeddings خود پشتیبانی می کند، از جمله Hugging Face Hub، Cohere، Llama-cpp، و Spacy.

کد پایتون زیر کمی از LangChain DeepLearning.AI تغییر یافته است آموزش آنلاین چت با داده های شما.


from langchain.embeddings.openai import OpenAIEmbeddings
embed_object = OpenAIEmbeddings()

from langchain.vectorstores import Chroma
chroma_store_directory = "docs/chroma_db"

vectordb = Chroma.from_documents(
    documents=my_split_docs,
    embedding=embed_object,
    persist_directory=chroma_store_directory
)

# Check how many embeddings were created
print(vectordb._collection.count())

به خط زیر در _collection.count() توجه کنید!

من ۳۰۶ جاسازی می بینم، همان تعداد تکه های متن ggplot2 من.

یک نکته دیگر برای مبتدیان پایتون: تورفتگی در پایتون اهمیت دارد. مطمئن شوید که خطوط بدون تورفتگی هیچ فاصله ای قبل از خود ندارند و خطوط فرورفته همگی از تعداد فاصله تورفتگی یکسانی استفاده می کنند.

در سیستم من به نظر می رسد که این کد داده ها را در دیسک ذخیره کرده است. با این حال، آموزش می گوید که باید کد پایتون زیر را اجرا کنیم تا جاسازی ها را برای استفاده بعدی ذخیره کنیم. من هم این کار را انجام خواهم داد، زیرا نمی‌خواهم جاسازی‌ها را دوباره ایجاد کنم، مگر اینکه سند تغییر کند.


vectordb.persist()

اکنون آماده سازی اسناد برای پرس و جو تمام شده است. من یک فایل جدید به نام qanda.py ایجاد می کنم تا از جاسازی های برداری که ایجاد کرده ایم استفاده کنیم.

مرحله ۵: درخواست کاربر را جاسازی کنید و تکه های سند را پیدا کنید

اکنون وقت آن است که یک سؤال بپرسید، جاسازی‌هایی برای آن سؤال ایجاد کنید، و اسنادی را که بیشتر مرتبط با سؤال هستند بر اساس جاسازی‌های تکه‌ها بازیابی کنید.

LangChain به لطف روش‌های داخلی شی vectordb راه‌های مختلفی را برای انجام همه این کارها در یک خط کد به ما می‌دهد. روش similarity_search() آن یک محاسبه ساده از شباهت های برداری انجام می دهد و شبیه ترین تکه های متن را برمی گرداند.

چند راه دیگر برای انجام این کار وجود دارد، از جمله max_marginal_relevance_search(). ایده پشت آن یکی این است که شما لزوماً سه تکه متن تقریباً یکسان را نمی خواهید. شاید اگر کمی تنوع در متن وجود داشته باشد تا اطلاعات مفید بیشتری به دست آورید، پاسخ غنی تری خواهید داشت. بنابراین، max_marginal_relevance_search() چند متن مرتبط‌تر از آنچه که واقعاً قصد دارید برای پاسخ به LLM ارسال کنید بازیابی می‌کند (شما تصمیم می‌گیرید که چند متن دیگر). سپس قطعات متن نهایی را انتخاب می‌کند، که دارای درجه‌ای از تنوع است.

شما مشخص می‌کنید که چه تعداد تکه متن مرتبط را می‌خواهید similarity_search() با آرگومان k آن برگرداند. برای max_marginal_relevance()، مشخص می‌کنید که ابتدا چند قطعه باید با fetch_k بازیابی شود، و چند قطعه متن نهایی را می‌خواهید LLM برای پاسخ خود با k.

اگر اسناد تغییر نکرده باشند، نمی‌خواهم فایل آماده‌سازی سند را اجرا کنم، بنابراین ابتدا بسته‌ها و متغیرهای محیطی لازم (به عنوان مثال، کلید OpenAI API من) را در qanda جدید بارگیری می‌کنم. فایل py، همانطور که قبل از استفاده از doc_prep.py انجام دادم. سپس، پایگاه داده برداری chromadb خود را بارگیری می کنم:


# If running from RStudio, remember to first run in R:
# library(reticulate)
# use_virtualenv("the_virtual_environment_you_set_up")
# api_key_py <- r_to_py(Sys.getenv("OPENAI_API_KEY"))

import openai
openai.api_key = r.api_key_for_py  
from langchain.embeddings.openai import OpenAIEmbeddings
embed_object = OpenAIEmbeddings()

from langchain.vectorstores import Chroma
chroma_store_directory = "docs/chroma_db"
vectordb = Chroma(persist_directory=chroma_store_directory, 
                  embedding_function=embed_object)

در مرحله بعد، یک سوال را به صورت سخت کد می نویسم و ​​اسناد مربوطه را بازیابی می کنم. توجه داشته باشید که من می توانم اسناد را با یک خط کد بازیابی کنم:


my_question = "How do you rotate text on the x-axis of a graph?"
# For straightforward similarity searching
sim_docs = vectordb.similarity_search(my_question)

# For maximum marginal relevance search retrieving 5 possible chunks and choosing 3 finalists:
mm_docs = vectordb.max_marginal_relevance_search(my_question, k = 3, fetch_k = 5)

اگر می خواهید قطعات سند بازیابی شده را مشاهده کنید، می توانید آنها را در پایتون با چیزی شبیه به زیر چاپ کنید:


for doc in mm_docs:
    print(doc.page_content)
    
for doc in sim_docs:
    print(doc.page_content)

به تورفتگی ها به عنوان بخشی از حلقه های for توجه کنید.

همچنین می‌توانید ابرداده‌های آنها را با:

مشاهده کنید


for doc in mm_docs:
    print(doc.metadata)
    
for docs in sim_docs:
    print(docs.metadata)

همانند سایر اشیاء، می‌توانید در R:

نیز به آنها نگاه کنید


mm_relevant <- py$mm_docs
sim_relevant <- py$sim_docs

من مطمئن نیستم که چرا مدل‌ها گاهی اوقات وقتی سه سند را درخواست می‌کنم، چهار سند را برمی‌گردانند، اما این مشکلی ایجاد نمی‌کند—مگر اینکه برای LLM هنگام عبور از متن برای ایجاد پاسخ، توکن‌های زیادی برای LLM وجود داشته باشد.

مرحله ۶: پاسخ خود را ایجاد کنید

اکنون زمان آن رسیده است که از یک LLM مانند GPT-3.5 بخواهید تا بر اساس اسناد مربوطه، پاسخ کتبی به سؤال کاربر ایجاد کند. می توانید این کار را با تابع RetrievalQA LangChain انجام دهید.

من پیشنهاد می‌کنم ابتدا الگوی پیش‌فرض LangChain را برای این کار امتحان کنید، که آسان است و اغلب برای نمونه‌سازی یا استفاده شخصی شما به خوبی کار می‌کند:


# Set up the LLM you want to use, in this example OpenAI's gpt-3.5-turbo
from langchain.chat_models import ChatOpenAI
the_llm = ChatOpenAI(model_name="gpt-3.5-turbo", temperature=0)

# Create a chain using the RetrievalQA component
from langchain.chains import RetrievalQA
qa_chain = RetrievalQA.from_chain_type(the_llm,retriever=vectordb.as_retriever())

# Run the chain on the question, and print the result
print(qa_chain.run(my_question))

هوش مصنوعی پاسخ زیر را ارسال کرد:


To rotate text on the x-axis of a graph, you can use the `theme()` function in ggplot2. Specifically, you can use the `axis.text.x` argument to modify the appearance of the x-axis text. Here is an example:

```R
library(ggplot2)

# Create a basic scatter plot
p <- ggplot(mtcars, aes(x = mpg, y = wt)) +
  geom_point()

# Rotate x-axis text by 45 degrees
p + theme(axis.text.x = element_text(angle = 45, hjust = 1))
```

In this example, the `angle` argument is set to 45, which rotates the x-axis text by 45 degrees. The `hjust` argument is set to 1, which aligns the text to the right. You can adjust the angle and alignment values to achieve the desired rotation and alignment of the x-axis text.

به نظر درست است!

اکنون که زنجیره راه‌اندازی شده است، می‌توانید آن را روی سؤالات دیگر فقط با یک دستور با استفاده از یک اسکریپت R اجرا کنید: 


py_run_string('
print(qa_chain.run("How can I make a bar chart where the bars are steel blue?"))
')

پاسخ این است:


```R
library(ggplot2)

# Create a bar chart with steel blue bars
p <- ggplot(mtcars, aes(factor(cyl)))
p + geom_bar(fill = "steelblue")
```

In this example, we use the `fill` aesthetic to specify the color of the bars as "steelblue". You can adjust the color to your preference by changing the color name or using a hexadecimal color code.

این پاسخ بهتری نسبت به زمانی است که من گاهی از ChatGPT 3.5 همین سوال را می‌پرسم. (گاهی اوقات کدی که ارسال می کند در واقع کار نمی کند.)

همچنین می‌توانید تأیید کنید که پاسخ‌ها از پایگاه دانش عمومی ChatGPT گرفته نشده‌اند، بلکه واقعاً از سندی که آپلود کرده‌اید می‌آیند. برای فهمیدن، می‌توانید چیزی کاملاً نامرتبط با ggplot2 بپرسید که در مستندات وجود ندارد:


py_run_string('
print(qa_chain.run("What is the capital of Australia?"))
')

شما باید برگردید:


I don't know.

اگر برنامه‌ای را برای استفاده گسترده‌تر ایجاد می‌کنید، “نمی‌دانم” ممکن است کمی مختصر باشد. اگر می‌توانید مستندات LangChain را بررسی کنید شما می خواهید قالب پیش فرض را سفارشی کنید. شخصی سازی پاسخ منطقی است اگر در حال ایجاد یک برنامه کاربردی برای بیش از خودتان یا یک تیم کوچک هستید.

ترفندهای قالب یکی از حوزه‌هایی است که LangChain ممکن است بیش از حد پیچیده به نظر برسد—برای اجرای تغییرات کوچک در یک الگو، ممکن است چندین خط کد نیاز باشد. با این حال، این یک ریسک در استفاده از هر چارچوب نظری است، و این به هر توسعه دهنده بستگی دارد که تصمیم بگیرد آیا مزایای کلی پروژه ارزش چنین هزینه هایی را دارد یا خیر. اگرچه بسیار محبوب است، همه طرفدار LangChain نیستند

چکار دیگری می توانید با LangChain انجام دهید؟

ساده‌ترین افزودن به برنامه تا کنون شامل اسناد بیشتر است. LangChain یک DirectoryLoader برای ساده کردن این کار دارد. اگر در چندین سند جستجو می کنید، ممکن است بخواهید بدانید از کدام اسناد برای ایجاد پاسخ استفاده شده است. می‌توانید آرگومان return_source_documents=True را به RetrievalQA اضافه کنید، مانند این:


qa_chain = RetrievalQA.from_chain_type(the_llm,retriever=vectordb.as_retriever(), return_source_documents=True) 
my_result = qa_chain({"query": my_question})
print(my_result['result'])

این کد در ابتدا فقط برای اجرای محلی برای یک کاربر مفید است، اما می‌تواند مبنای منطقی برای یک برنامه وب تعاملی با استفاده از چارچوبی مانند Streamlit یا Shiny برای پایتون باشد. یا، پایتون و R را ترکیب می‌کنید، پاسخ نهایی LLM را به R ارسال می‌کنید و یک برنامه با استفاده از چارچوب وب Shiny R ایجاد می‌کنید (اگرچه من متوجه شده‌ام که استقرار یک برنامه Shiny با پایتون و R تا حدودی پیچیده است).

توجه داشته باشید که این برنامه از نظر فنی یک “ربات چت” نیست زیرا سوالات قبلی شما را به خاطر نمی آورد. بنابراین، شما نمی توانید یک “مکالمه” مانند “چگونه می توانم اندازه متن تیتر یک نمودار را تغییر دهم؟” به دنبال آن “افسانه چطور؟” شما باید هر سوال جدید را به طور کامل بنویسید، مانند “چگونه اندازه تیتر یک افسانه را تغییر دهید؟”

با این حال، می‌توانید با هدف ConversationBufferMemory.

منابع بیشتر

برای کسب اطلاعات بیشتر درباره LangChain، علاوه بر اسناد LangChain، یک سرور LangChain Discord وجود دارد که دارای یک ربات چت هوش مصنوعی، kapa.ai است، که می تواند اسناد را پرس و جو کند.

من تقریباً یک سوم از برنامه‌های مبتنی بر LLM را توسعه داده‌ام با LangChain توسط ادن مارکو، و تا کنون مفید بوده است. در حالی که آن دوره می گوید که شما باید «در پایتون مهارت داشته باشید»، من فکر می کنم دانستن زبان های برنامه نویسی دیگر به همراه تمایل به انجام زیاد جستجو/ChatGPT کافی است.

برای اطلاعات در مورد Streamlit و LangChain، چندین آموزش در سایت Streamlit وجود دارد، از جمله آموزش LangChain شماره ۱: ساختن یک برنامه مبتنی بر LLM در ۱۸ خط کد.

در نهایت، وینستون چانگ از Posit در حال کار بر روی یک بسته جریانی چت برای Python درخشان که شامل یک رابط “جریان” می شود، بنابراین پاسخ LLM به تدریج بر اساس کاراکتر یا کلمه ظاهر می شود، همانطور که ChatGPT نشان می دهد، به جای همه به یکباره مانند این مثال ها.