ساخت یک چت بات هوشمند با OpenAI و Pinecone: یک راهنمای ساده


نویسنده(های): آبیشک چوداری

در ابتدا منتشر شد به سمت هوش مصنوعی.

این مقاله به شما نشان می دهد که چگونه با استفاده از پایتون یک چت بات ساده RAG بسازید کاج برای پایگاه داده برداری و مدل تعبیه، OpenAI برای LLM، و LangChain برای گردش کار RAG.

توهمات

چت ربات های مبتنی بر مدل زبان بزرگ (LLM)، به ویژه آنهایی که از آنها استفاده می کنند هوش مصنوعی مولد (GenAI)، ابزارهای فوق العاده قدرتمندی برای پاسخگویی به طیف وسیعی از سوالات هستند. آنها بر روی حجم وسیعی از داده های متنی آموزش دیده اند و قادر به ایجاد پاسخ های منسجم و مرتبط با زمینه هستند. با این حال، زمانی که از این مدل‌ها سوالاتی پرسیده می‌شود که شامل اطلاعات خاص یا خصوصی است که در مورد آنها آموزش ندیده‌اند، محدودیت ایجاد می‌شود. در چنین مواردی، ربات چت ممکن است پاسخ هایی روان و مطمئن اما در واقع نادرست تولید کند. این پدیده که به نام «توهم“یک چالش رایج در برنامه های کاربردی LLM است.

https://circleci.com/blog/llm-hallucinations-ci

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

RAG چگونه کار می کند؟

https://pub.towardsai.net/rag-explained-key-component-in-large-language-model-llm-e9b8e2083a45

برای پرداختن به این موضوع، چارچوبی به نام Retrieval-Augmented Generation (RAG) پدید آمده است. RAG قابلیت های LLM ها را با یکپارچه سازی منابع دانش خارجی افزایش می دهد و به طور موثر احتمال توهم را کاهش می دهد. RAG به جای تکیه صرف بر دانش از پیش آموزش‌دیده مدل، با بازیابی اطلاعات مرتبط از یک پایگاه داده خارجی – اغلب یک پایگاه داده برداری مانند Pinecone – که حاوی جدیدترین یا خصوصی است، کار می‌کند.

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

برای اطلاعات بیشتر در مورد RAG مراجعه کنید: https://research.ibm.com/blog/retrieval-augmented-generation-RAG

پیش نیازها

قبل از شروع مطمئن شوید که موارد زیر را دارید:

بیایید بسته های مورد نیاز را با استفاده از موارد زیر نصب کنیم:

! pip install \
"pinecone[grpc]" \
"langchain-pinecone" \
"langchain-openai" \
"langchain-text-splitters" \
"langchain" \
"jupyter" \
"python-dotenv"

متغیرهای محیطی را برای کلیدهای Pinecone و OpenAI API خود در .env فایل و آنها را همانطور که در زیر ذکر شده است بخوانید

# Content of .env file
PINECONE_API_KEY="" # available at app.pinecone.io
OPENAI_API_KEY="" # available at platform.openai.com/api-keys
import os
from dotenv import load_dotenv
load_dotenv()
PINECONE_API_KEY = os.getenv('PINECONE_API_KEY')
OPENAI_API_KEY = os.getenv('OPENAI_API_KEY')

ذخیره دانش در Pinecone

ما با سندی کار خواهیم کرد که یک محصول خیالی به نام “WonderVector5000” را توصیف می کند، که چیزی است که مدل های زبان بزرگ (LLM) هیچ دانش قبلی درباره آن ندارند. برای فعال کردن LLM برای پاسخگویی مؤثر به سؤالات مربوط به این محصول، ابتدا باید یک نمایه Pinecone ایجاد کنیم.

در مرحله بعد، ما از چارچوب LangChain برای تقسیم سند به بخش های کوچکتر و قابل مدیریت استفاده خواهیم کرد، فرآیندی که به نام “تکه تکه شدن

بعد از تکه تکه شدن در سند، ما جاسازی برداری را برای هر یک از این بخش ها با استفاده از قابلیت های استنتاج Pinecone ایجاد می کنیم. این جاسازی های برداری معنای معنایی متن را به تصویر می کشد و به عنوان کلید بازیابی اطلاعات دقیق عمل می کند.

در نهایت، ما این جاسازی‌های برداری را در فهرست Pinecone شما اضافه می‌کنیم (یعنی درج یا به‌روزرسانی می‌کنیم)، تا هر زمان که LLM نیاز به دسترسی به اطلاعات خاصی در مورد WonderVector5000 داشته باشد، داده‌ها را به راحتی برای بازیابی در دسترس قرار می‌دهیم.

با دنبال کردن این مراحل، سیستمی ایجاد می‌کنیم که در آن LLM می‌تواند به این منبع دانش خارجی مراجعه کند تا پاسخ‌های دقیقی ارائه دهد، حتی برای موضوعاتی که در ابتدا در مورد آنها آموزش ندیده است. بیایید شروع کنیم:

یک شاخص کمتر از سرور در Pinecone برای ذخیره جاسازی‌های سند خود ایجاد کنید

بیایید یک را ایجاد کنیم ایندکس بدون سرور در Pinecone برای ذخیره جاسازی های سند ما. هنگام تنظیم شاخص، باید دو پارامتر مهم را پیکربندی کنیم: ابعاد شاخص و متریک فاصله. اینها باید با مشخصات آن مطابقت داشته باشند multilingual-e5-large مدل، که ما از آن برای تولید جاسازی ها استفاده خواهیم کرد.

https://docs.pinecone.io/models/multilingual-e5-large

ابعاد شاخص اندازه نمایش برداری تولید شده توسط مدل را مشخص می کند، در حالی که متریک فاصله تعیین می کند که شباهت بین بردارها چگونه اندازه گیری می شود.

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

# Imports
from pinecone.grpc import PineconeGRPC as Pinecone
from pinecone import ServerlessSpec
import os
pc = Pinecone(api_key=PINECONE_API_KEY)
index_name = "docs-rag-chatbot"
if not pc.has_index(index_name):
pc.create_index(
name=index_name,
dimension=1024,
metric="cosine",
spec=ServerlessSpec(
cloud="aws",
region="us-east-1"
)
)
# Read mardown file
f = open("WonderVector5000.MD", "r")
markdown_document = f.read()
markdown_document[:100]
'# The WonderVector5000: A Journey into Absurd Innovation\n\n## Introduction\n\nWelcome to the whimsical '

سند را به تکه های کوچکتر تقسیم کنید

از آنجایی که سند ما در قالب Markdown است، باید محتوا را تکه تکه کنید بر اساس ساختار آن اطمینان حاصل شود که هر بخش از نظر معنایی منسجم است. این رویکرد معنای هر بخش را حفظ می کند و بازیابی اطلاعات مربوطه را بعدا آسان تر می کند. پس از تکه تکه شدن محتوا، از آن استفاده خواهیم کرد استنباط کاج برای ایجاد جاسازی برای هر تکه. در نهایت، ما این جاسازی‌ها را در فهرست Pinecone خود قرار می‌دهیم، و آنها را برای بازیابی در آینده در دسترس قرار می‌دهیم و توانایی LLM برای پاسخگویی دقیق به سؤالات را افزایش می‌دهیم.

# Imports
from langchain_pinecone import PineconeEmbeddings
from langchain_pinecone import PineconeVectorStore
from langchain_text_splitters import MarkdownHeaderTextSplitter
import os
import time
# Specify markdown splitter fields
headers_to_split_on = [
("##", "Header 2")
]

markdown_splitter = MarkdownHeaderTextSplitter(
headers_to_split_on=headers_to_split_on, strip_headers=False
)
# Split the markdown document
md_header_splits = markdown_splitter.split_text(markdown_document)
md_header_splits[0]

Document(metadata={'Header 2': 'Introduction'}, page_content="# The WonderVector5000: A Journey into Absurd Innovation \n## Introduction \nWelcome to the whimsical world of the WonderVector5000, an astonishing leap into the realms of imaginative technology. This extraordinary device, borne of creative fancy, promises to revolutionize absolutely nothing while dazzling you with its fantastical features. Whether you're a seasoned technophile or just someone looking for a bit of fun, the WonderVector5000 is sure to leave you amused and bemused in equal measure. Let's explore the incredible, albeit entirely fictitious, specifications, setup process, and troubleshooting tips for this marvel of modern nonsense.")

تکه ها را جاسازی کنید

برای این ابتدا باید مدل تعبیه را تعریف کنیم و سپس هر تکه را جاسازی کنیم و سپس جاسازی را در نمایه کاج قرار دهیم.

# Initialize a LangChain embedding object.
model_name = "multilingual-e5-large"
embeddings = PineconeEmbeddings(
model=model_name,
pinecone_api_key=PINECONE_API_KEY
)
embeddings
PineconeEmbeddings(model='multilingual-e5-large', batch_size=96, query_params={'input_type': 'query', 'truncation': 'END'}, document_params={'input_type': 'passage', 'truncation': 'END'}, dimension=1024, show_progress_bar=False, pinecone_api_key=SecretStr('**********'))
# Embed each chunk and upsert the embeddings into your Pinecone index.
docsearch = PineconeVectorStore.from_documents(
documents=md_header_splits,
index_name=index_name,
embedding=embeddings,
namespace="wondervector5000"
)
docsearch
langchain_pinecone.vectorstores.PineconeVectorStore at 0x7fd6c3ad4310>

برای مشاهده تکه ها از Pinecone درخواست کنید

با استفاده از Pinecone’s list و query عملیات می توانیم به یکی از رکوردها نگاه کنیم

index = pc.Index(index_name)
namespace = "wondervector5000"
for ids in index.list(namespace=namespace):
query = index.query(
id=ids[0],
namespace=namespace,
top_k=1,
include_values=True,
include_metadata=True
)
print(query)
{'matches': [{'id': '7d593c7b-7580-43ca-a1eb-084a001c27ed',
'metadata': {'Header 2': 'Product overview',
'text': '## Product overview \n'
'The WonderVector5000 is packed with '
'features that defy logic and physics, each '
'designed to sound impressive while '
'maintaining a delightful air of '
'absurdity: \n'
'- Quantum Flibberflabber Engine: The heart '
'of the WonderVector5000, this engine '
'operates on principles of quantum '
'flibberflabber, a phenomenon as mysterious '
"as it is meaningless. It's said to harness "
'the power of improbability to function '
'seamlessly across multiple dimensions. \n'
'- Hyperbolic Singularity Matrix: This '
'component compresses infinite '
'possibilities into a singular hyperbolic '
'state, allowing the device to predict '
'outcomes with 0% accuracy, ensuring every '
'use is a new adventure. \n'
'- Aetherial Flux Capacitor: Drawing energy '
'from the fictional aether, this flux '
'capacitor provides unlimited power by '
'tapping into the boundless reserves of '
'imaginary energy fields. \n'
'- Multi-Dimensional Holo-Interface: '
'Interact with the WonderVector5000 through '
'its holographic interface that projects '
'controls and information in '
'three-and-a-half dimensions, creating a '
"user experience that's simultaneously "
'futuristic and perplexing. \n'
'- Neural Fandango Synchronizer: This '
'advanced feature connects directly to the '
"user's brain waves, converting your "
'deepest thoughts into tangible '
'actions—albeit with results that are '
'whimsically unpredictable. \n'
'- Chrono-Distortion Field: Manipulate time '
"itself with the WonderVector5000's "
'chrono-distortion field, allowing you to '
'experience moments before they occur or '
'revisit them in a state of temporal flux.'},
'score': 1.0,
'sparse_values': {'indices': [], 'values': []},
'values': [0.030090332,
0.0046539307,
...]}],
'namespace': 'wondervector5000',
'usage': {'read_units': 6}}

از ربات چت استفاده کنید

اکنون که سند ما به‌عنوان جاسازی‌شده در Pinecone ذخیره می‌شود، می‌توانیم دقت پاسخ‌های LLM را با بازیابی دانش مرتبط از فهرست Pinecone خود هنگام ارسال سؤالات، افزایش دهیم. این تضمین می کند که LLM به اطلاعات خاصی که برای ایجاد پاسخ های دقیق نیاز دارد دسترسی دارد.

در مرحله بعد، یک شی LangChain را برای تعامل با آن مقداردهی اولیه می کنیم GPT-3.5-turbo LLM. ما چند سوال درباره محصول خیالی WonderVector5000 تعریف می کنیم و آنها را دو بار به LLM ارسال می کنیم: ابتدا با دانش مربوطه بازیابی شده از Pinecone و سپس بدون هیچ دانش اضافی. این به ما امکان می دهد کیفیت و دقت پاسخ ها را در هر دو سناریو مقایسه کنیم.

# Imports
from langchain.chains import RetrievalQA
from langchain_openai import ChatOpenAI
# Initialize a LangChain object for chatting with the LLM
# without knowledge from Pinecone.
llm = ChatOpenAI(
openai_api_key=OPENAI_API_KEY,
model_name='gpt-3.5-turbo',
temperature=0.0
)
# Initialize a LangChain object for chatting with the LLM
# with knowledge from Pinecone.
qa = RetrievalQA.from_chain_type(
llm=llm,
chain_type="stuff",
retriever=docsearch.as_retriever()
)
# Define a few questions about the WonderVector5000.
query1 = """What are the first 3 steps for getting started
with the WonderVector5000?"""

query2 = """The Neural Fandango Synchronizer is giving me a
headache. What do I do?"""

# Send each query to the LLM twice, first with relevant knowledge from Pincone 
# and then without any additional knowledge.
print("Query 1\n")
print("Chat with knowledge:")
print(qa.invoke(query1).get("result"))
print("\nChat without knowledge:")
print(llm.invoke(query1).content)
Query 1

Chat with knowledge:
The first three steps for getting started with the WonderVector5000 are:

1. Unpack the Device: Remove the WonderVector5000 from its anti-gravitational packaging, ensuring to handle with care to avoid disturbing the delicate balance of its components.
2. Initiate the Quantum Flibberflabber Engine: Locate the translucent lever marked “QFE Start” and pull it gently. You should notice a slight shimmer in the air as the engine engages, indicating that quantum flibberflabber is in effect.
3. Calibrate the Hyperbolic Singularity Matrix: Turn the dials labeled "Infinity A" and "Infinity B" until the matrix stabilizes. You’ll know it's calibrated correctly when the display shows a single, stable “∞”.

Chat without knowledge:
1. Unpack the WonderVector5000 and familiarize yourself with all the components and accessories included in the package.
2. Read the user manual thoroughly to understand the setup process, safety precautions, and operating instructions.
3. Connect the WonderVector5000 to a power source and follow the instructions in the manual to calibrate the device and start using it for your desired applications.

print("\nQuery 2\n")
print("Chat with knowledge:")
print(qa.invoke(query2).get("result"))
print("\nChat without knowledge:")
print(llm.invoke(query2).content)
Query 2

Chat with knowledge:
To address the headache caused by the Neural Fandango Synchronizer, ensure that the headband is correctly positioned and not too tight on your forehead. Additionally, try to relax and focus on simple, calming thoughts to ease the synchronization process.

Chat without knowledge:
If the Neural Fandango Synchronizer is giving you a headache, it is important to stop using it immediately and give yourself a break. Take some time to rest and relax, drink plenty of water, and consider taking over-the-counter pain medication if needed. If the headache persists or worsens, it is recommended to consult a healthcare professional for further evaluation and advice. Additionally, you may want to consider adjusting the settings or usage of the Neural Fandango Synchronizer to see if that helps alleviate the headache.

برای هر پرس و جو، تفاوت واضحی در کیفیت پاسخ ها مشاهده خواهید کرد. اولین پاسخ، که دانش مربوطه را از نمایه Pinecone ترکیب می‌کند، اطلاعات بسیار دقیقی را ارائه می‌کند که دقیقاً با محتوای سند WonderVector5000 مطابقت دارد. از سوی دیگر، پاسخ دوم، که بدون دانش اضافی از Pinecone ایجاد شده است، ممکن است قانع کننده به نظر برسد، اما معمولاً عمومی و اغلب نادرست است. این تضاد اهمیت تقویت LLM با داده های خارجی برای پاسخ های دقیق و مرتبط را برجسته می کند.

منتشر شده از طریق به سمت هوش مصنوعی



منبع: https://towardsai.net/p/machine-learning/building-a-smart-chatbot-with-openai-and-pinecone-a-simple-guide