速通RAG之离婚小助手

项目名称:RAG离婚小助手

报告日期:2024年8月18日

项目负责人:我

(嘿嘿)还是用微信昵称吧:快乐旭

NVIDIA训练营要结束了,经过几天的学习也确实学到了不少知识,但是又不知道做点啥,没有好点子,思来想去决定整个活,既简单能速通,又满足了我整活的欲望哈哈哈哈。

项目概述:

在我们日常生活中总会使用AI,但是有的时候它的回答并不令人满意,往往过于笼统。

比如这样:

好像什么都说了又什么都没说,并不能解决实际问题,那是因为这个AI并没有学习大量关于该问题的知识,基于这个问题,我利用RAG技术输入了一些法律知识进去,就能很好解决这个问题。

技术方案与实施步骤:

采用phi-3-small-128k-instruct这个模型

数据结构:txt婚姻法文档——因为txt最简单,其他法律文档也行,我这个只是个整活示例,但是法律条文作为数据的好处是非常容易处理,一条法律条文一行,条理特别清晰,很适合新手。

实施步骤:

环境:实训班给的现成的环境,我也说不清楚,但是自己还是大致统计了一下:

langchain_nvidia_ai_endpoints

getpass

openai

os

tqdm

pathlib

faiss

langchain

langchain_core

operator

实施步骤:

Try NVIDIA NIM APIs申请一个apikey就行

import getpass
import os

if os.environ.get("NVIDIA_API_KEY", "").startswith("nvapi-"):
    print("Valid NVIDIA_API_KEY already in environment. Delete to reset")
else:
    nvapi_key = getpass.getpass("NVAPI Key (starts with nvapi-): ")
    assert nvapi_key.startswith("nvapi-"), f"{nvapi_key[:5]}... is not a valid key"
    os.environ["NVIDIA_API_KEY"] = nvapi_key

然后初始化向量模型

from langchain_nvidia_ai_endpoints import NVIDIAEmbeddings

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

 获取数据(这里是婚姻法)——注意文件路径自己改一下

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("./zh_data/")
data = []
sources = []
for p in ps:
    if p.endswith('.txt'):
        path2file="./zh_data/"+p
        with open(path2file,encoding="utf-8") as f:
            lines=f.readlines()
            for line in lines:
                if len(line)>=1:
                    data.append(line)
                    sources.append(path2file)
# 清楚文档空行
documents=[d for d in data if d != '\n']

 处理文档并保存

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))

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

重读一下,以后直接读就行,不用上面再次处理

# Load the vectorestore back.
store = FAISS.load_local("./zh_data/nv_embedding", embedder,allow_dangerous_deserialization=True)

 可以提问了

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("怎么离婚?")

 结果展示:

比之前好多了嘿嘿

 问题与解决方案:

毕竟是速通,能跑就行,问题肯定是有的

1.文本如果过多,处理速度变慢,可以修改并提供高质量数据

2.txt文本过于单一,并不支持所有类型数据,这个还要做数据处理

3.文本手动添加,也许可以试一试爬虫

项目总结与展望:

这次训练营学了很多东西,未来可以尝试使用Gradio整个页面看看,也可以试一试用生成语音回答,还有就是我觉得法律条文的逻辑结构刚好适合RAG来处理哈哈哈。

参考资料:

中华人民共和国婚姻法 (gqb.gov.cn)

(真有人学代码去看婚姻法吗?)狗头

  • 11
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值