大模型的清醒之道:详解RAG实现,告别幻觉困扰

项目名称:AI-AGENT夏季训练营 —医疗专家智能机器人

一、项目概述

        总所周知,当前大模型面临幻觉问题、知识更新滞后和计算资源消耗大的痛点。RAG(检索增强生成)通过结合检索机制和生成模型,有效提升了信息生成的准确性和可靠性,同时弥补了私有化知识不足问题,广泛应用于问答系统、客户支持、医疗咨询、法律咨询等场景。

        本项目介绍基于RAG的实现医疗专家智能机器人,使用NVDIA提供的LLM + LangChain框架 + faiss向量数据库 + streamlit前端展示,整体上简单易懂,小白也可以很轻松实现自己RAG系统。

二、技术方案与实施步骤

2.1 技术方案

2.1.1 RAG工作流程

2.1.2 模型选择

nvidia_ai_endpoints提供了众多模型,下面代码可以查看支持的模型

from langchain_nvidia_ai_endpoints import ChatNVIDIA
ChatNVIDIA.get_available_models()

        模型选择可以根据特定的业务场景来选择,通常模型越大(LLM),准确度越高,当然依赖的计算资源越大,费用也越贵,速度越慢。当前,小模型(SLM)越来越受到关注,在一般的GPU,甚至手机嵌入式设备上可以跑起来,经过微调SLM,效果也不错。所以本项目采用SLM模型:phi-3-small-8k-instruct。

2.1.3 数据的构建

- 数据准备和预处理

        从网上收集了关于疾病症状对应的数据,并进行预处理,删除噪点

- 数据分段

        由于向量化模型的上下文长度有限,需要对数据进行分段后向量模型才能处理,分段长度一般在200~500。

- 数据向量化&存储

        通过向量模型,可以把特定的文本数据转成多维的向量数据,并存储在向量数据库中,供后续查询。

        向量化检索和传统字符检索,向量化充分考虑了句子语义,情感,上下语句关联等,匹配结果更优。

2.2 实施步骤

2.2.1 环境安装

- 安装miniconda

        大家可以根据自己的网络情况从下面的地址下载安装,比较简单,这里忽略

- 创建python虚拟环境(python >= 3.8)

conda create --name ai-robot python=3.8
conda activate ai-robot

2.2.2 安装python依赖包

pip install langchain-nvidia-ai-endpoints jupyterlab langchain_core langchain faiss-cpu==1.7.2 openai numpy langchain-community streamlit -i https://pypi.tuna.tsinghua.edu.cn/simple/

2.2.3 代码实现

- 设置NVIDIA KEY
import getpass
import os

# 设置 NVIDIA API ke
nvapi_key = getpass.getpass("Enter your NVIDIA API key: ")
os.environ["NVIDIA_API_KEY"] = nvapi_key
- 加载SLM
from langchain_nvidia_ai_endpoints import ChatNVIDIA

# 加载SLM
llm = ChatNVIDIA(model="ai-phi-3-small-8k-instruct", nvidia_api_key=nvapi_key, max_tokens=512)
- 加载数据和预处理
import os
from tqdm import tqdm
from pathlib import Path

# Here we read in the text data and prepare them into vectorstore
ps = os.listdir("./rag_data/")
data = []
sources = []
for p in ps:
    if p.endswith('.txt'):
        path2file="./rag_data/"+p
        with open(path2file,encoding="utf-8") as f:
            for line in f.readlines():
                if line:
                    data.append(line)
                    sources.append(path2file)
documents=[d for d in data if d != '\n']

        documents就是预处理完的数据

- 数据分段
from operator import itemgetter
from langchain.vectorstores import FAISS
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import RunnablePassthrough
from langchain.text_splitter import CharacterTextSplitter
from langchain_nvidia_ai_endpoints import ChatNVIDIA
import faiss

text_splitter = CharacterTextSplitter(chunk_size=400, separator=" ")
docs = []
metadatas = []

for i, d in enumerate(documents):
    splits = text_splitter.split_text(d)
    #print(len(splits))
    docs.extend(splits)
    metadatas.extend([{"source": sources[i]}] * len(splits))

        docs就是分段后的数据,metadatas对应元数据

- 数据向量化&存储
from langchain_nvidia_ai_endpoints import NVIDIAEmbeddings

embedder = NVIDIAEmbeddings(model="ai-embed-qa-4")

store = FAISS.from_texts(docs, embedder , metadatas=metadatas)
store.save_local('./rag_data/nv_embedding')

        加载向量化模型ai-embed-qa-4,并存储在faiss向量化数据库中

- 问答
retriever = store.as_retriever()

prompt = ChatPromptTemplate.from_messages(
    [
        (
            "system",
            "Answer solely based on the following context:\n<Documents>\n{context}\n</Documents>",
        ),
        ("user", "{question}"),
    ]
)

chain = (
    {"context": retriever, "question": RunnablePassthrough()}
    | prompt
    | llm
    | StrOutputParser()
)

chain.invoke("我头晕,没有食欲,怕冷,可能是什么疾病?")

        RAG回答:

' 根据提供的文档,您的症状可能与甲状腺功能减退有关。然而,建议您及时就医进行诊断和适当的治疗。'
- 前端交互页面设计

使用steamlit作为前端页面设计框架

import streamlit as st


st.set_page_config(
    page_title="医疗专家智能机器人演示",
    page_icon=":robot:",
    layout='wide'
)



st.title("医疗专家智能机器人")


if 'history' not in st.session_state:
    st.session_state.history = []

if 'past_key_values' not in st.session_state:
    st.session_state.past_key_values = None

for i, (query, response) in enumerate(st.session_state.history):
    with st.chat_message(name="user", avatar="user"):
        st.markdown(query)
    with st.chat_message(name="assistant", avatar="assistant"):
        st.markdown(response)
with st.chat_message(name="user", avatar="user"):
    input_placeholder = st.empty()
with st.chat_message(name="assistant", avatar="assistant"):
    message_placeholder = st.empty()

prompt_text = st.text_area(label="用户输入",
                           height=100,
                           placeholder="请在这儿输入您的咨询的症状描述")

button = st.button("发送", key="predict")

if button:
    input_placeholder.markdown(prompt_text)
    history, past_key_values = st.session_state.history, st.session_state.past_key_values
    message_placeholder.markdown(chain.invoke(question))
    st.session_state.history = history
    st.session_state.past_key_values = past_key_values

运行

streamlit run robot.py

至此,医疗专家智能机器人搭建完成!

三、项目成果与展示

        医疗专家智能机器人应用于网络医疗就诊,帮助广大用户初步排查疾病以及医疗建议。

        用户输入对应症状,医疗专家智能机器人输出对应可能的疾病。

四、项目总结与展望

        本项目的实现比较简单,主要针对初学者,旨在快速了解RAG大模型应用,在实际产品中需要考虑很多因素,如如何提高RAG索引精度,多模态RAG,RAG多跳问题处理等等。

  • 13
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值