IRIS-RAG-Gen_ IRIS Vector Search による ChatGPT RAG アプリケーションのパーソナライズ
コミュニティの皆さん、こんにちは。
この記事では、iris-RAG-Gen という私のアプリケーションをご紹介します。
iris-RAG-Gen は、IRIS Vector Search の機能を使用して、Streamlit ウェブフレームワーク、LangChain、および OpenAI で ChatGPT をパーソナライズするジェネレーティブ AI 検索拡張生成(RAG: Retrieval-Augmented Generation)アプリケーションです。 このアプリケーションは IRIS をベクトルストアとして使用します。
アプリケーションの機能
- ドキュメント(PDF または TXT)を IRIS に取り込む
- 選択されたドキュメントの取り込みを使ってチャットする
- ドキュメントの取り込みを削除する
- OpenAI ChatGPT
ドキュメント(PDF または TXT)を IRIS に取り込む
以下の手順に従って、ドキュメントを取り込みます。
- OpenAI キーを入力します。
- ドキュメント(PDF または TXT)を選択します。
- ドキュメントの説明を入力します。
- 「Ingest Document」ボタンをクリックします。
ドキュメントの取り込み機能は、ドキュメントの詳細を rag_documents テーブルに挿入し、ベクトルデータを保存する 'rag_document + id'(rag_documents の ID)テーブルを作成します。

以下の Python コードは選択されたドキュメントをベクトルに保存します。
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.document_loaders import PyPDFLoader, TextLoader
from langchain_iris import IRISVector
from langchain_openai import OpenAIEmbeddings
from sqlalchemy import create_engine,text
classRagOpr:#Ingest document. Parametres contains file path, description and file type defingestDoc(self,filePath,fileDesc,fileType):
embeddings = OpenAIEmbeddings()
#Load the document based on the file typeif fileType == "text/plain":
loader = TextLoader(filePath)
elif fileType == "application/pdf":
loader = PyPDFLoader(filePath)
<span class="hljs-comment">#load data into documents</span>
documents = loader.load()
text_splitter = RecursiveCharacterTextSplitter(chunk_size=<span class="hljs-number">400</span>, chunk_overlap=<span class="hljs-number">0</span>)
<span class="hljs-comment">#Split text into chunks</span>
texts = text_splitter.split_documents(documents)
<span class="hljs-comment">#Get collection Name from rag_doucments table. </span>
COLLECTION_NAME = self.get_collection_name(fileDesc,fileType)
<span class="hljs-comment"># function to create collection_name table and store vector data in it.</span>
db = IRISVector.from_documents(
embedding=embeddings,
documents=texts,
collection_name = COLLECTION_NAME,
connection_string=self.CONNECTION_STRING,
)
<span class="hljs-comment">#Get collection name</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get_collection_name</span><span class="hljs-params">(self,fileDesc,fileType)</span>:</span>
<span class="hljs-comment"># check if rag_documents table exists, if not then create it </span>
<span class="hljs-keyword">with</span> self.engine.connect() <span class="hljs-keyword">as</span> conn:
<span class="hljs-keyword">with</span> conn.begin():
sql = text(<span class="hljs-string">"""
SELECT *
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'SQLUser'
AND TABLE_NAME = 'rag_documents';
"""</span>)
result = []
<span class="hljs-keyword">try</span>:
result = conn.execute(sql).fetchall()
<span class="hljs-keyword">except</span> Exception <span class="hljs-keyword">as</span> err:
print(<span class="hljs-string">"An exception occurred:"</span>, err)
<span class="hljs-keyword">return</span> <span class="hljs-string">''</span>
<span class="hljs-comment">#if table is not created, then create rag_documents table first</span>
<span class="hljs-keyword">if</span> len(result) == <span class="hljs-number">0</span>:
sql = text(<span class="hljs-string">"""
CREATE TABLE rag_documents (
description VARCHAR(255),
docType VARCHAR(50) )
"""</span>)
<span class="hljs-keyword">try</span>:
result = conn.execute(sql)
<span class="hljs-keyword">except</span> Exception <span class="hljs-keyword">as</span> err:
print(<span class="hljs-string">"An exception occurred:"</span>, err)
<span class="hljs-keyword">return</span> <span class="hljs-string">''</span>
<span class="hljs-comment">#Insert description value </span>
<span class="hljs-keyword">with</span> self.engine.connect() <span class="hljs-keyword">as</span> conn:
<span class="hljs-keyword">with</span> conn.begin():
sql = text(<span class="hljs-string">"""
INSERT INTO rag_documents
(description,docType)
VALUES (:desc,:ftype)
"""</span>)
<span class="hljs-keyword">try</span>:
result = conn.execute(sql, {<span class="hljs-string">'desc'</span>:fileDesc,<span class="hljs-string">'ftype'</span>:fileType})
<span class="hljs-keyword">except</span> Exception <span class="hljs-keyword">as</span> err:
print(<span class="hljs-string">"An exception occurred:"</span>, err)
<span class="hljs-keyword">return</span> <span class="hljs-string">''</span>
<span class="hljs-comment">#select ID of last inserted record</span>
sql = text(<span class="hljs-string">"""
SELECT LAST_IDENTITY()
"""</span>)
<span class="hljs-keyword">try</span>:
result = conn.execute(sql).fetchall()
<span class="hljs-keyword">except</span> Exception <span class="hljs-keyword">as</span> err:
print(<span class="hljs-string">"An exception occurred:"</span>, err)
<span class="hljs-keyword">return</span> <span class="hljs-string">''</span>
<span class="hljs-keyword">return</span> <span class="hljs-string">"rag_document"</span>+str(result[<span class="hljs-number">0</span>][<span class="hljs-number">0</span>])</code></pre>
管理ポータルで以下の SQL コマンドを入力し、ベクトルデータを取得します。
SELECT top 5id, embedding, document, metadata
FROM SQLUser.rag_document2

選択されたドキュメントの取り込みを使ってチャットする
チャットオプションの選択セクションから「Document」を選択して質問を入力します。アプリケーションはベクトルデータを読み取り、関連する回答を返します。

以下の Python コードは、選択されたドキュメントをべく鳥に保存します。
from langchain_iris import IRISVector
from langchain_openai import OpenAIEmbeddings,ChatOpenAI
from langchain.chains import ConversationChain
from langchain.chains.conversation.memory import ConversationSummaryMemory
from langchain.chat_models import ChatOpenAI
classRagOpr:defragSearch(self,prompt,id):#Concat document id with rag_doucment to get the collection name
COLLECTION_NAME = "rag_document"+str(id)
embeddings = OpenAIEmbeddings()
#Get vector store reference
db2 = IRISVector (
embedding_function=embeddings,
collection_name=COLLECTION_NAME,
connection_string=self.CONNECTION_STRING,
)
#Similarity search
docs_with_score = db2.similarity_search_with_score(prompt)
#Prepair the retrieved documents to pass to LLM
relevant_docs = ["".join(str(doc.page_content)) + " "for doc, _ in docs_with_score]
#init LLM
llm = ChatOpenAI(
temperature=0,
model_name="gpt-3.5-turbo"
)
#manage and handle LangChain multi-turn conversations
conversation_sum = ConversationChain(
llm=llm,
memory= ConversationSummaryMemory(llm=llm),
verbose=False
)
#Create prompt
template = f"""
Prompt: {prompt}
Relevant Docuemnts: {relevant_docs}
"""#Return the answer
resp = conversation_sum(template)
return resp['response']
</code></pre>
詳細については、iris-RAG-Gen の Open Exchange アプリケーションページをご覧ください。
よろしくお願いします。