[TOC] # Langchain-對話02 https://python.langchain.com/docs/get_started/quickstart#diving-deeper-1 Retrieval(檢索):https://python.langchain.com/docs/modules/data_connection/ Chains(鏈):https://python.langchain.com/docs/modules/chains/#lcel-chains ## **基本流程:** ``` mermaid graph LR; Input-->Prompt; Prompt-->LLM; LLM-->Output; ``` ```python= from langchain_openai import ChatOpenAI from langchain_core.prompts import ChatPromptTemplate OPENAI_API_KEY="sk-YOUR API KEY" llm = ChatOpenAI(openai_api_key=OPENAI_API_KEY) prompt = ChatPromptTemplate.from_messages([ ("system", "你是世界一流的程式語言專家。"), ("user", "{input}") ]) messages = prompt.format_messages(input="使用Python寫一個經典的貪吃蛇遊戲") print(llm.invoke(messages).content) ``` ## **Retrieval Chain 流程:** ``` mermaid graph LR; Input-->Prompt; Input-->Document_chain; Document_chain-->Retrieval_chain; Retrieval_chain-->Prompt; Prompt-->LLM; LLM-->Output; ``` `pip install faiss-cpu` ```python= from langchain_core.documents import Document from langchain.chains.combine_documents import create_stuff_documents_chain from langchain.chains import create_retrieval_chain from langchain_core.prompts import ChatPromptTemplate from langchain_core.documents import Document from langchain_core.prompts import ChatPromptTemplate from langchain_openai import ChatOpenAI from langchain_community.vectorstores import FAISS from langchain_openai import OpenAIEmbeddings import os OPENAI_API_KEY="sk-YOUR API KEY" os.environ['OPENAI_API_KEY'] = OPENAI_API_KEY llm = ChatOpenAI(openai_api_key=OPENAI_API_KEY) # First we need a prompt that we can pass into an LLM to generate this search query docs = [ Document(page_content='本校大學部四年制學生須修習共同必修英文課程,即大一共同必修英文及多元英文必修課程, 共12學分,並應參加「入學英文分級會考」(以下簡稱會考)及通過「校定英文能力檢測」(0學分),始得畢業。'), Document(page_content='會考於每年新生入學前舉行,其結果作為英文課程分級教學及編入修課模組之依據。'), Document(page_content='學生依入學英檢成績,分別編入基礎、中階、進階修課模組,並依各模組規定修讀及抵免共同必修英文課程。大一共同必修英文課程 及 多元英文必 修 課程模組參照附錄二。'), ] embeddings = OpenAIEmbeddings() vectordb = FAISS.from_documents(docs, embeddings) retriever = vectordb.as_retriever() prompt = ChatPromptTemplate.from_messages([ ('system', 'Answer the user\'s questions in Chinese, based on the context provided below:\n\n{context}'), ('user', 'Question: {input}'), ]) document_chain = create_stuff_documents_chain(llm, prompt) retrieval_chain = create_retrieval_chain(retriever, document_chain) context = [] #紀錄上一個LLM的對話答案 input_text = input('>>> ') while input_text.lower() != 'exit': response = retrieval_chain.invoke({ 'input': input_text, 'context': context }) print(response['answer']) context = response['context'] input_text = input('>>> ') ``` **執行結果** ``` >>> 大學生有哪些英文規定? 大學生須修習共同必修英文課程,包括大一共同必修英文及多元英文必修課程,共12學分。此外,學生還需參加「入學英文分級會考」和通過「校定英文能力檢測」,方可畢業。根據入學英檢成績,學生將被分為基礎、中階、進階修課模組,並依各模組規定修讀及抵免共同必修英文課程。 ``` ### Retrieval Module(檢索模組)-使用embedding model將資料轉成向量儲存在FAISS中 https://python.langchain.com/docs/modules/data_connection/ 將資料轉換成向量後,再與問題進行相似比對 * 文字 ``` txt = [ '本校大學部四年制學生須修習共同必修英文課程,即大一共同必修英文及多元英文必修課程, 共12學分,並應參加「入學英文分級會考」(以下簡稱會考)及通過「校定英文能力檢測」(0學分),始得畢業。會考於每年新生入學前舉行,其結果作為英文課程分級教學及編入修課模組之依據。學生依入學英檢成績,分別編入基礎、中階、進階修課模組,並依各模組規定修讀及抵免共同必修英文課程。大一共同必修英文課程 及 多元英文必 修 課程模組參照附錄二。' ] embeddings = OpenAIEmbeddings() vectordb = FAISS.from_texts(txt, embeddings) ``` * 文件 ``` docs = [ Document(page_content='本校大學部四年制學生須修習共同必修英文課程,即大一共同必修英文及多元英文必修課程, 共12學分,並應參加「入學英文分級會考」(以下簡稱會考)及通過「校定英文能力檢測」(0學分),始得畢業。'), Document(page_content='會考於每年新生入學前舉行,其結果作為英文課程分級教學及編入修課模組之依據。'), Document(page_content='學生依入學英檢成績,分別編入基礎、中階、進階修課模組,並依各模組規定修讀及抵免共同必修英文課程。大一共同必修英文課程 及 多元英文必 修 課程模組參照附錄二。'), ] embeddings = OpenAIEmbeddings() vectordb = FAISS.from_documents(docs, embeddings) ``` * 檔案 ``` loader = PyPDFLoader("台科大英文畢業門檻.pdf") pages = loader.load_and_split() docs = [ pages[0], pages[1], pages[2], pages[3], pages[4], ] embeddings = OpenAIEmbeddings() vectordb = FAISS.from_documents(docs, embeddings) ``` ### Retrieval Module(檢索模組)-document_chain與retrieval_chain * **document_chain**:將資料轉成向量後,建立的文檔鏈(document_chain)。 [連結](https://api.python.langchain.com/en/latest/chains/langchain.chains.combine_documents.stuff.create_stuff_documents_chain.html#langchain.chains.combine_documents.stuff.create_stuff_documents_chain) ```python response = document_chain.invoke({ 'input': input_text, 'context': docs #文檔資料 }) ``` * **retrieval_chain**:將資料轉成向量後,**先從資料中找出與問題(Input)最相關的資料**,再建立的檢索鏈(retrieval_chain)。 [連結](https://api.python.langchain.com/en/latest/chains/langchain.chains.retrieval.create_retrieval_chain.html#langchain.chains.retrieval.create_retrieval_chain) * 這個答案應該會更準確! ```python retrieval_chain = create_retrieval_chain(retriever, document_chain) response = retrieval_chain.invoke({ 'input': input_text, 'context': context #紀錄上一個LLM的對話答案(可略) }) ``` ## **Conversation Retrieval Chain 流程:** 對話應該要考慮整個對話紀錄 ``` mermaid graph LR; Input-->LLM; ChatHistory-->LLM; LLM-->NewQuestion; NewQuestion-->Retrieval_Chain_Module; Retrieval_Chain_Module-->Output; ``` ```python= from langchain_core.prompts import ChatPromptTemplate from langchain.chains import create_history_aware_retriever from langchain_core.prompts import MessagesPlaceholder from langchain_openai import ChatOpenAI from langchain_community.vectorstores import FAISS from langchain_openai import OpenAIEmbeddings from langchain_core.messages import HumanMessage, AIMessage from langchain_core.documents import Document from langchain.chains.combine_documents import create_stuff_documents_chain from langchain.chains import create_retrieval_chain import os OPENAI_API_KEY="sk-YOUR API KEY" os.environ['OPENAI_API_KEY'] = OPENAI_API_KEY llm = ChatOpenAI(openai_api_key=OPENAI_API_KEY) docs = [ Document(page_content='本校大學部四年制學生須修習共同必修英文課程,即大一共同必修英文及多元英文必修課程, 共12學分,並應參加「入學英文分級會考」(以下簡稱會考)及通過「校定英文能力檢測」(0學分),始得畢業。'), Document(page_content='會考於每年新生入學前舉行,其結果作為英文課程分級教學及編入修課模組之依據。'), Document(page_content='學生依入學英檢成績,分別編入基礎、中階、進階修課模組,並依各模組規定修讀及抵免共同必修英文課程。大一共同必修英文課程 及 多元英文必 修 課程模組參照附錄二。'), ] embeddings = OpenAIEmbeddings() vectordb = FAISS.from_documents(docs, embeddings) retriever = vectordb.as_retriever() prompt = ChatPromptTemplate.from_messages([ ('system', 'Answer the user\'s questions in Chinese, based on the context provided below:\n\n{context}'), MessagesPlaceholder(variable_name="chat_history"), ('user', 'Question: {input}'), ]) chat_history = [HumanMessage(content="我是台灣科技大學的大學生"), AIMessage(content="我知道了!")] document_chain = create_stuff_documents_chain(llm, prompt) retriever_chain = create_history_aware_retriever(llm, retriever, prompt) retrieval_chain = create_retrieval_chain(retriever_chain, document_chain) context = [] #紀錄上一個LLM的對話答案 input_text = input('>>> ') while input_text.lower() != 'exit': response = retrieval_chain.invoke({ "chat_history": chat_history, 'input': input_text, 'context': context, }) print(response['answer']) context = response['context'] input_text = input('>>> ') ``` ``` >>> 我是哪所大學? 你是台灣科技大學的大學生。 >>> 大學生有哪些英文規定? 根據您所提供的資訊,本校大學部四年制學生須修習共同必修英文課程,包括大一共同必修英文及多元英文必修課程,共12學分。此外,學生還需要參加「入學英文分 級會考」以及通過「校定英文能力檢測」,方可畢業。根據入學英檢成績,學生會被編入基礎、中階、進階修課模組,並依各模組規定修讀或抵免共同必修英文課程。 会考每年新生入學前舉行,其結果將影響學生在英文課程中的分級和修課模組。 >>> 我是哪所大學? 你是台灣科技大學的大學生。 ``` ### Retrieval(檢索模組)-conversation history * **document_chain**:建立一個鏈,用於將文件清單傳遞給模型。[連結](https://api.python.langchain.com/en/latest/chains/langchain.chains.combine_documents.stuff.create_stuff_documents_chain.html#langchain.chains.combine_documents.stuff.create_stuff_documents_chain) * **retriever_chain**:創建歷史對話的鏈,回傳問題(Input)相關文檔。 [連結](https://api.python.langchain.com/en/latest/chains/langchain.chains.history_aware_retriever.create_history_aware_retriever.html#langchain.chains.history_aware_retriever.create_history_aware_retriever) * **retrieval_chain**:建立檢索鏈(文件和歷史資料)來檢索文件然後將它們傳遞給模型。[連結](https://api.python.langchain.com/en/latest/chains/langchain.chains.retrieval.create_retrieval_chain.html#langchain.chains.retrieval.create_retrieval_chain) ```python document_chain = create_stuff_documents_chain(llm, prompt) retriever_chain = create_history_aware_retriever(llm, retriever, prompt) retrieval_chain = create_retrieval_chain(retriever_chain, document_chain) ``` ## 參考資料 LangChain(#retrieval-chain):https://python.langchain.com/docs/get_started/quickstart#retrieval-chain Tutorial: ChatGPT Over Your Data:https://blog.langchain.dev/tutorial-chatgpt-over-your-data/ ## 延伸學習 LangChain 怎麼玩? Retrieval 篇,來做個聊天機器人(ChatBot)吧:https://myapollo.com.tw/blog/langchain-tutorial-retrieval/ LLM RAG:https://medium.com/@drjulija/what-are-naive-rag-advanced-rag-modular-rag-paradigms-edff410c202e document_loaders:https://python.langchain.com/docs/modules/data_connection/document_loaders/