PostgreSQL और पायथन के लिए Azure डेटाबेस के साथ RAG एप्लिकेशन बनाएं
अब जब डेटाबेस एम्बेडिंग और वेक्टर इंडेक्स के साथ तैयार हो गया है, तो पुनर्प्राप्ति को एक कार्यशील एप्लिकेशन में बदलने का समय आ गया है। लक्ष्य सरल है: एक उपयोगकर्ता प्रश्न लें, PostgreSQL से सबसे प्रासंगिक अंश प्राप्त करें, और LangChain के माध्यम से Azure OpenAI का उपयोग करके उन हिस्सों पर आधारित उत्तर उत्पन्न करें।
इस इकाई में, आप पायथन में आरएजी एप्लिकेशन बनाने की मूल बातें सीखते हैं। एप्लिकेशन डेटाबेस से जुड़ता है, डेटाबेस पर एक समानता खोज चलाता है, और मतिभ्रम से बचने के लिए स्पष्ट निर्देशों के साथ खोज परिणामों को एक मॉडल को भेजता है। चूंकि मॉडल डेटाबेस डेटा के आधार पर एक अच्छी तरह से परिभाषित संदर्भ प्राप्त करता है, इसलिए यह उस संदर्भ में आधारित अधिक सटीक और प्रासंगिक उत्तर उत्पन्न कर सकता है।
PostgreSQL और LangChain के साथ Retrieval-Augmented पीढ़ी
हमारी पिछली इकाइयों से याद रखें, आरएजी प्रवाह चरणों का एक समूह है जो पुनर्प्राप्ति और पीढ़ी को जोड़ता है। आइए इसे तोड़ें:
- उपयोगकर्ता एक प्रश्न पूछता है।
- डेटाबेस प्रश्न के लिए एक एम्बेडिंग की गणना करता है और डेटाबेस (शीर्ष विखंडों) में निकटतम मिलान खोजने के लिए वेक्टर अनुक्रमणिका का उपयोग करता है।
- शीर्ष खंड मॉडल को एक संकेत के साथ पारित किए जाते हैं जो कहता है: "केवल इस संदर्भ से उत्तर दें। यदि आप नहीं जानते हैं, तो ऐसा कहें।
- मॉडल प्रदान किए गए संदर्भ के आधार पर एक प्राकृतिक भाषा उत्तर देता है।
LangChain भाषा मॉडल के साथ अनुप्रयोगों के निर्माण के लिए एक रूपरेखा प्रदान करता है। यह विभिन्न डेटा स्रोतों से जुड़ने, संकेतों को प्रबंधित करने और प्रतिक्रियाओं को संभालने की प्रक्रिया को सरल बनाता है। PostgreSQL के लिए Azure डेटाबेस को पायथन और लैंगचेन के साथ जोड़कर, आप एक शक्तिशाली RAG एप्लिकेशन बना सकते हैं जो प्रासंगिक जानकारी प्राप्त करता है और सटीक प्रतिक्रियाएँ उत्पन्न करता है। जबकि आपका RAG एप्लिकेशन विकसित हो सकता है, ये मूल सिद्धांत इसके विकास का मार्गदर्शन करते हैं।
इस एप्लिकेशन में, आप Azure OpenAI सेवा के साथ इंटरैक्ट करने के लिए LangChain AzureChatOpenAI रैपर का उपयोग करते हैं।
निम्न पायथन उदाहरणों के लिए, आप निम्न तालिका संरचना का उपयोग करें:
CREATE TABLE company_policies (
id SERIAL PRIMARY KEY,
title TEXT,
policy_text TEXT,
embedding VECTOR(1536)
);
इस तालिका में, आप मानते हैं कि कुशल समानता खोजों को सक्षम करने के लिए स्तंभ पर embedding एक वेक्टर अनुक्रमणिका बनाई गई है।
आइए प्रत्येक चरण के लिए पायथन कोड स्निपेट की समीक्षा करें। अधिकांश आरएजी एप्लिकेशन एक समान संरचना का पालन करते हैं।
डेटाबेस से कनेक्ट करें
कनेक्शन अल्पकालिक और सुरक्षित रखें। इस उदाहरण में, रहस्य पर्यावरण चर में हैं और कनेक्शन को पारित किए गए हैं।
import os, psycopg2
from contextlib import contextmanager
@contextmanager
def get_conn():
conn = psycopg2.connect(
host=os.getenv("PGHOST"),
user=os.getenv("PGUSER"),
password=os.getenv("PGPASSWORD"),
dbname=os.getenv("PGDATABASE"),
connect_timeout=10
)
try:
yield conn
finally:
conn.close()
यह स्क्रिप्ट डेटाबेस कनेक्शन के लिए एक संदर्भ प्रबंधक स्थापित करती है, यह सुनिश्चित करती है कि वे उपयोग के बाद ठीक से बंद हैं। वास्तविक पुनर्प्राप्ति पर जाने का समय।
प्रासंगिक अंश पुनः प्राप्त करें
चूंकि उपयोगकर्ता कोई प्रश्न पूछ रहा है, इसलिए आपको उस प्रश्न के साथ डेटाबेस को क्वेरी करने के लिए एक फ़ंक्शन की आवश्यकता है। उस फ़ंक्शन को प्रश्न के आधार पर प्रासंगिक विखंडू वापस करना चाहिए। यह उदाहरण मानता है कि वेक्टर इंडेक्स को कोसाइन दूरी का उपयोग करके रैंक किया गया है, इसलिए आप क्वेरी करने के लिए संबंधित ऑपरेटर वर्ग (=<>) का उपयोग करते हैं।
def retrieve_chunks(question, top_k=5):
sql = """
WITH q AS (
SELECT azure_openai.create_embeddings(%s, %s)::vector AS qvec
)
SELECT id, title, policy_text
FROM company_policies, q
ORDER BY embedding <=> q.qvec
LIMIT %s;
"""
params = (os.getenv("OPENAI_EMBED_DEPLOYMENT"), question, top_k)
with get_conn() as conn, conn.cursor() as cur:
cur.execute(sql, params)
rows = cur.fetchall()
return [{"id": r[0], "title": r[1], "text": r[2]} for r in rows]
तो यह फ़ंक्शन उपयोगकर्ता के प्रश्न के आधार पर डेटाबेस से प्रासंगिक अंश प्राप्त करता है। इन विखंडों का उपयोग तब बाद के चरण में संदर्भ-जागरूक उत्तर उत्पन्न करने के लिए किया जाता है।
LangChain के साथ एक उत्तर उत्पन्न करें
अब जब आपके पास प्रासंगिक विखंडू को पुनः प्राप्त करने के लिए एक फ़ंक्शन है, तो आपको उन विखंडू का उपयोग करके एक उत्तर उत्पन्न करने की आवश्यकता है। मॉडल को केवल पुनर्प्राप्त संदर्भ का उपयोग करना चाहिए और नीति शीर्षकों का हवाला देना चाहिए। उत्तर जनरेशन फ़ंक्शन बनाने का समय।
from langchain_openai import AzureChatOpenAI
SYSTEM_PROMPT = """
You are a helpful assistant. Answer using ONLY the provided context.
If the answer is not in the context, say you don’t have enough information.
Cite policy titles in square brackets, e.g., [Vacation policy].
"""
def format_context(chunks):
return "\n\n".join([f"[{c['title']}] {c['text']}" for c in chunks])
def generate_answer(question, chunks):
llm = AzureChatOpenAI(
azure_deployment=os.getenv("OPENAI_CHAT_DEPLOYMENT"),
api_key=os.getenv("AZURE_OPENAI_API_KEY"),
azure_endpoint=os.getenv("AZURE_OPENAI_ENDPOINT"),
api_version=os.getenv("AZURE_OPENAI_API_VERSION"),
temperature=0
)
context = format_context(chunks)
messages = [
("system", SYSTEM_PROMPT),
("human", f"Question: {question}\nContext:\n{context}")
]
return llm.invoke(messages).content
नोट
AzureChatOpenAI का उपयोग करने के लिए:
- संदेशों को (भूमिका, सामग्री) टुपल्स (या संदेश ऑब्जेक्ट्स) की सूची के रूप में पास करें।
- env vars और कंस्ट्रक्टर के माध्यम से Azure सेटिंग्स प्रदान करें:
AZURE_OPENAI_API_KEY, ,AZURE_OPENAI_ENDPOINTऔरazure_deployment,api_version. - तथ्यात्मक उत्तरों के लिए रखें
temperature=0। बड़े मूल्य रचनात्मकता को बढ़ाते हैं लेकिन सटीकता को कम कर सकते हैं।
यह फ़ंक्शन आरएजी एप्लिकेशन का मूल है, जो भाषा मॉडल के साथ बातचीत को संभालता है। ध्यान दें कि पुनर्प्राप्त किए गए विखंडू कैसे स्वरूपित होते हैं और संदर्भ में शामिल होते हैं। इसके अतिरिक्त, सिस्टम प्रॉम्प्ट को यह सुनिश्चित करने के लिए डिज़ाइन किया गया है कि मॉडल प्रदान किए गए संदर्भ का पालन करता है और एआई-जनित प्रतिक्रियाओं को कम करता है जो गलत हो सकती हैं। अंत में, संदेशों को भाषा मॉडल द्वारा संसाधित किया जाता है ताकि LangChainआह्वान विधि का उपयोग करके प्रतिक्रिया उत्पन्न की जा सके। विधि को invoke स्वरूपित संदेशों के साथ कहा जाता है, और मॉडल की प्रतिक्रिया प्राकृतिक भाषा पाठ के रूप में लौटा दी जाती है।
इसे एक साथ बांधें
आखिरी चीज जो आपको चाहिए वह है पूर्ण प्रवाह को चलाने के लिए एक सरल कार्य:
def answer_question(question):
chunks = retrieve_chunks(question)
if not chunks:
return "I couldn’t find relevant content in the policy store."
return generate_answer(question, chunks)
# Quick test
print(answer_question("How many vacation days do employees get?"))
इस उदाहरण में, आप डेटाबेस से प्रासंगिक अंश प्राप्त करते हैं और संदर्भ-जागरूक उत्तर उत्पन्न करने के लिए उनका उपयोग करते हैं। यह फ़ंक्शन कॉल प्रश्न से उत्तर पीढ़ी तक पूर्ण प्रवाह को प्रदर्शित करता है। सबसे पहले यह प्रासंगिक संदर्भ प्राप्त करने के लिए फ़ंक्शन को retrieve_chunks कॉल करता है (मूल रूप से डेटाबेस से लौटाए गए पंक्तियाँ)। यह फ़ंक्शन तब उस संदर्भ को उस फ़ंक्शन में पास generate_answer करता है जो अंतिम उत्तर (संदर्भ के हिस्से के रूप में पंक्तियों का उपयोग करके) का उत्पादन करने के लिए भाषा मॉडल के साथ इंटरैक्ट करता है। पूर्ण प्रवाह यह सुनिश्चित करता है कि उत्तर पुनर्प्राप्त डेटा पर आधारित है, जो अधिक सटीक और विश्वसनीय प्रतिक्रिया प्रदान करता है।
मुख्य टेकअवे
एक व्यावहारिक आरएजी एप्लिकेशन एक उपयोगकर्ता प्रश्न लेता है, एसक्यूएल में एक एम्बेडिंग बनाता है, डेटाबेस में निकटतम मार्ग लाने के लिए एक वेक्टर इंडेक्स का उपयोग करता है, और केवल उस संदर्भ को मॉडल को सौंपता है। मतिभ्रम को कम करने के लिए, मॉडल को दिए गए संदर्भ के भीतर रहने और जानकारी गायब होने पर स्वीकार करने का भी निर्देश दिया जाता है। कनेक्शन को अल्पकालिक रखें, प्रश्नों को पैरामीटर करें और पर्यावरण चर के माध्यम से रहस्य पास करें। तथ्यात्मक उत्तरों के लिए कम तापमान का उपयोग करें और हल्के उद्धरण (शीर्षक या आईडी) शामिल करें ताकि प्रतिक्रियाएं पता लगाई जा सकें।
अब आपको इस बात की ठोस समझ होनी चाहिए कि PostgreSQL और Pythonके लिए Azure डेटाबेस का उपयोग करके पुनर्प्राप्ति संवर्धित पीढ़ी (RAG) एप्लिकेशन कैसे बनाया जाए। जबकि आपका RAG एप्लिकेशन वास्तविक दुनिया के परिदृश्य में बहुत अधिक जटिल हो सकता है, मूल सिद्धांत समान रहते हैं।