当前位置: 首页 > article >正文

【RAG 项目实战 05】重构:封装代码

【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 添加历史对话能力

http://www.kler.cn/a/410217.html

相关文章:

  • 基于Boost库的搜索引擎
  • 浅谈网络 | 传输层之TCP协议
  • 网络原理(一):应用层自定义协议的信息组织格式 初始 HTTP
  • 浏览器缓存与协商缓存
  • 网络爬虫——分布式爬虫架构
  • 深度学习:神经网络中线性层的使用
  • King‘s IOT :实验室设备及环境物联监控预警系统
  • Flask 创建API接口服务
  • 学习threejs,使用设置bumpMap凹凸贴图创建褶皱,实现贴图厚度效果
  • JDK1.8新增特性
  • Java 面经 - HashMap
  • 深入探索Go语言中的sync.Mutex与sync.RWMutex:原理、应用与实践
  • Git Github Gitlab与Gitee的关系
  • 如何在 Eclipse 中调试ABAP程序
  • 【vim】vim怎么把某一列内容复制到另一列
  • 长短时记忆网络(SLTM):理解与实践
  • 基于web的音乐网站(Java+SpringBoot+Mysql)
  • 用 Python 从零开始创建神经网络(十):优化器(Optimizers)(持续更新中...)
  • 利用Google的OR-Tools解决智能调度问题
  • 小程序-基于java+SpringBoot+Vue的美食推荐系统设计与实现
  • 无监督跨域目标检测的语义一致性知识转移
  • vxe-grid table 修改表格数据校验的主题样式
  • 深入解析分布式遗传算法及其Python实现
  • 基于YOLOv8深度学习的智慧农业棉花采摘状态检测与语音提醒系统(PyQt5界面+数据集+训练代码)
  • 一场开源视角的AI会议即将在南京举办
  • 线性代数空间理解