【RAG 專案實戰 05】重構:封裝程式碼
NLP Github 專案:
-
NLP 專案實踐:fasterai/nlp-project-practice
介紹:該倉庫圍繞著 NLP 任務模型的設計、訓練、最佳化、部署和應用,分享大模型演算法工程師的日常工作和實戰經驗
-
AI 藏經閣:https://gitee.com/fasterai/ai-e-book
介紹:該倉庫主要分享了數百本 AI 領域電子書
-
AI 演算法面經:fasterai/nlp-interview-handbook#面經
介紹:該倉庫一網打盡網際網路大廠NLP演算法面經,演算法求職必備神器
-
NLP 劍指Offer:https://gitee.com/fasterai/nlp-interview-handbook
介紹:該倉庫彙總了 NLP 演算法工程師高頻面題
- 新增 common.py
- 改造 llm_util.py
- 新增 chain_util.py
- 新增 msg_util.py
- 改造 app.py
新增 common.py
# @Author:青松
# 公眾號:FasterAI
# Python, version 3.10.14
# Pytorch, version 2.3.0
# Chainlit, version 1.1.301
class Constants:
MODEL_NAME = {
'QianFan': 'QianFan'
}
改造 llm_util.py
# @Author:青松
# 公眾號:FasterAI
# Python, version 3.10.14
# Pytorch, version 2.3.0
# Chainlit, version 1.1.301
from common import Constants
from langchain_community.chat_models import QianfanChatEndpoint
# 載入環境變數
from dotenv import load_dotenv
load_dotenv()
def get_llm(model_name):
llm = None
try:
if model_name == Constants.MODEL_NAME['QianFan']:
llm = QianfanChatEndpoint(
streaming=True,
model="ERNIE-Speed-8K",
)
except:
llm = get_default_llm()
finally:
if llm is None:
llm = get_default_llm()
return llm
def get_default_llm():
default_llm = QianfanChatEndpoint(
streaming=True,
model="ERNIE-Speed-8K",
)
return default_llm
新增 chain_util.py
# @Author:青松
# 公眾號:FasterAI
# Python, version 3.10.14
# Pytorch, version 2.3.0
# Chainlit, version 1.1.301
from langchain.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import MessagesPlaceholder
from langchain_core.runnables import RunnablePassthrough
from langchain_core.vectorstores import VectorStore
def get_chat_chain(llm):
# 提示模板中新增 chat_history
prompt = ChatPromptTemplate.from_messages(
[
(
"system",
"你是一箇中國古詩詞專家,能準確的一字不差的背誦很多古詩詞,請用你最大的能力來回答使用者的問題。",
),
MessagesPlaceholder("chat_history"),
("human", "{question}"),
]
)
chat_chain = prompt | llm | StrOutputParser()
return chat_chain
新增 msg_util.py
# @Author:青松
# 公眾號:FasterAI
# Python, version 3.10.14
# Pytorch, version 2.3.0
# Chainlit, version 1.1.301
import chainlit as cl
from langchain_core.chat_history import BaseChatMessageHistory
from langchain_core.runnables import RunnableConfig
from langchain_core.runnables.history import RunnableWithMessageHistory
from langchain_community.chat_message_histories import ChatMessageHistory
# 儲存對話歷史
store = {}
def get_session_history(session_id: str) -> BaseChatMessageHistory:
if session_id not in store:
store[session_id] = ChatMessageHistory()
return store[session_id]
async def send_welcome_msg():
# todo: 新增 FasterAI 知識星球圖片以及 FastAI 知識庫地址
image = cl.Image(url="https://qingsong-1257401904.cos.ap-nanjing.myqcloud.com/wecaht.png")
# 傳送一個圖片
await cl.Message(
content="**青松** 邀你關注 **FasterAI**, 讓每個人的 AI 學習之路走的更容易些!立刻掃碼開啟 AI 學習、面試快車道 **(^_^)** ",
elements=[image],
).send()
async def response_with_history_by_astream(message: cl.Message, chain, session_id):
# 用 RunnableWithMessageHistory 包裝 Chain 新增對話歷史能力
runnable_with_history = RunnableWithMessageHistory(
chain,
get_session_history,
input_messages_key="question",
history_messages_key="chat_history",
)
msg = cl.Message(content="")
# 配置中使用 session_id 進行大模型互動
async for chunk in runnable_with_history.astream(
{"question": message.content},
config=RunnableConfig(configurable={"session_id": session_id},
callbacks=[cl.LangchainCallbackHandler()])
):
await msg.stream_token(chunk)
await msg.send()
改造 app.py
# @Author:青松
# 公眾號:FasterAI
# Python, version 3.10.14
# Pytorch, version 2.3.0
# Chainlit, version 1.1.301
import chainlit as cl
from common import Constants
import chain_util
import llm_util
import msg_util
# 獲取大模型例項
llm = llm_util.get_llm(Constants.MODEL_NAME['QianFan'])
@cl.password_auth_callback
def auth_callback(username: str, password: str):
""" 持久化客戶端聊天曆史程式碼,不需要請刪除 """
if (username, password) == ("admin", "admin"):
return cl.User(
identifier="admin", metadata={"role": "admin", "provider": "credentials"}
)
else:
return None
@cl.on_chat_start
async def on_chat_start():
""" 監聽會話開始事件 """
# 新增 session_id
cl.user_session.set('session_id', 'abc2')
# 傳送歡迎資訊
await msg_util.send_welcome_msg()
# 初始化鏈
init_chains()
@cl.on_message
async def on_message(message: cl.Message):
""" 監聽使用者訊息事件 """
# 獲得對話鏈
chat_chain = cl.user_session.get("chat_chain")
# 獲取當前的 session_id
session_id = cl.user_session.get("session_id")
# 使用對話歷史透過 astream 的方式響應使用者訊息
await msg_util.response_with_history_by_astream(message, chat_chain, session_id)
def init_chains():
""" 初始化系統中的鏈 """
# 對話鏈
chat_chain = chain_util.get_chat_chain(llm)
cl.user_session.set("chat_chain", chat_chain)
【動手學 RAG】系列文章:
- 【RAG 專案實戰 01】在 LangChain 中整合 Chainlit
- 【RAG 專案實戰 02】Chainlit 持久化對話歷史
- 【RAG 專案實戰 03】優雅的管理環境變數
- 【RAG 專案實戰 04】新增多輪對話能力
- 【RAG 專案實戰 05】重構:封裝程式碼
- 【RAG 專案實戰 06】使用 LangChain 結合 Chainlit 實現文件問答
- 【RAG 專案實戰 07】替換 ConversationalRetrievalChain(單輪問答)
- 【RAG 專案實戰 08】為 RAG 新增歷史對話能力
本文由mdnice多平臺釋出