大语言模型 (LLM) 在领域应用中,非常重要的理论是检索增强生成( Retrieval Augmented Generation,RAG)。本文利用 LLM + RAG,实现法律领域(面向法官/律师)的示例项目。
本文是 LLM + RAG 的 HelloWorld
项目,只包含了少量代码(核心代码)。有助于在 RAG 理论的基础上,进一步理解大模型领域应用。
项目地址:
- GitHub:github.com/xiaolinstar...
- Gitee:gitee.com/xingxiaolin...
前言
通用大语言模型是一个能说会道,能言善辩的语言大师。然而,当面对专业问题时,"不懂装懂",甚至"一本正经胡说八道"也不足为奇,属于是样样通,样样松 的百事通(联想到黄磊老师😊),该问题属于大语言模型的幻觉(Hallucinations)问题。
解决大模型的幻觉问题是一个非常具有价值的研究方向,在领域应用中使用 RAG 理论可以一定程度上解决该问题,简单理解为大模型外挂知识库。
可以这么理解,用户向一名专家请教问题时,不止提出问题,还拿着很多上下文信息(Context),这个时候专家在解答问题时,不止是自己脑子里储备的知识,还可以有效参考你提供的 Context,实现更准确的回答。
本文的灵感来源于阿里云社区的一篇文章《面向法律场景的大模型 RAG 检索增强解决方案》,我本计划按照该文章的步骤一步步实现,但发现其中夹带了私货(需要花钱购买阿里云的服务,还非常贵),并且在案例实现与效果演示环节存在缺陷。因此,决定创造出一篇更好的入门文章。
在阅读了《动手学大模型应用开发》的博客文章后,我动手实践,并将上述文章要做的事作为 Demo,既作为分享,也作为自己的学习作业。
仅仅听课做例题是不够的,还要做课后练习,才能对知识有更深刻的理解。
介绍
大语言模型领域应用中涉及到一些关键理论和技术,本文简单介绍最核心的若干个。
LangChain 大模型应用开发框架
我的理解: 类比深度学习领域中的 PyTorch(Like PyTorch but for LLM)。
官方简介: LangChain 是一个用于构建 LLM 驱动的应用程序的框架。它可以帮助您将可互操作的组件和第三方集成链接在一起,以简化 AI 应用程序开发。同时随着底层技术的发展做出面向未来的决策。
DeepSeek 介绍: LangChain 是一个用于构建基于大语言模型(LLM)应用的框架,旨在简化开发流程,帮助开发者更高效地创建复杂的 LLM 驱动应用。它提供了一系列工具和模块,支持链式调用、数据感知和交互能力,使 LLM 能够与外部数据源、工具和环境进行集成。
RAG 检索增强生成
检索增强生成(RAG)是通过检索外部知识库获取相关信息,并将其与大模型的生成能力结合,从而增强模型的专业性和准确性,使其能够提供更符合期望的回答。
使用数学语言理解,传统大模型应用:
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> R e s p o n s e l l m = L L M ( q u e r y ) Response_{llm} = LLM(query) </math>Responsellm=LLM(query)
RAG 应用:
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> R e s p o n s e r a g = L L M ( q u e r y , R A G ( q u e r y ) ) Response_{rag} = LLM(query, RAG(query)) </math>Responserag=LLM(query,RAG(query))
其中 <math xmlns="http://www.w3.org/1998/Math/MathML"> L L M ( ⋅ ) LLM(\cdot) </math>LLM(⋅) 为大语言模型函数如DeepSeek、ChatGPT、Qwen等, <math xmlns="http://www.w3.org/1998/Math/MathML"> R A G ( ⋅ ) RAG(\cdot) </math>RAG(⋅) 为知识库(向量数据库)函数。
LLM 大语言模型
大语言模型(Large Language Model,LLM),不知道为什么现在国内互联中把 Language 省略,称为"大模型"。
以下内容摘自 《维基百科-大型语言模型》 词条
大型语言模型 (Large Language Model,LLM),也称大语言模型 ,是由具有大量参数(通常数十亿个权重或更多)的人工神经网络组成的一类语言模型,使用自监督学习 或半监督学习对大量未标记文本进行训练。大语言模型在2018年左右出现,并在各种任务中表现出色。
尽管这个术语没有正式的定义,但它通常指的是参数数量在数十亿或更多数量级的模型。大语言模型是通用模型,在广泛的任务中表现出色,而不是针对一项特定任务(例如情感分析、命名实体识别或数学推理)进行训练。
Embedding 嵌入模型
在检索增强上,使用了嵌入 Embedding 理论,一种具体表现形式为 Word2Vec。 Embedding 或 Word2Vec 是将词语映射到低维向量空间的技术,通过捕捉词语之间的语义关系,使得机器能够理解和处理自然语言。
Word2Vec 是深度学习领域的核心理论,2 篇发表于 2013 年的文章,在 Google 学术上引用量高达 46k。
VectorDB 向量数据库
向量数据库是一种专为高效存储和检索高维向量数据而设计的数据库系统。这些向量通常来源于机器学习和深度学习模型对非结构化数据(如文本、图像、音频、视频)的编码处理。通过将原始数据转化为密集的数值向量,向量数据库能够支持诸如相似性搜索、推荐系统、图像检索、语音识别等多种应用场景。
列举一些常见向量数据库:
数据库 | 公开性 | GitHub Stars | 实现语言 | 许可证 |
---|---|---|---|---|
Milvus | 开源 | 33.2k | Go | Apache License V2 |
Faiss | 开源 | 33.7k | C++ | MIT |
Chroma | 开源 | 18.6k | Rust | Apache License V2 |
Pinecone | 非开源 | - | - | - |
就以我看到的应用项目,Milvus 和 Chroma 是最普遍使用的。
App 快速开发
《动手学大模型应用开发》中介绍的示例项目,使用 Gradio 和 Streamlit 快速构建大模型应用,此处不作过多介绍。
LLM-Law 大模型法律领域应用
知识库是互联网上随便找了些案例《保护未成年人权益十大优秀案例》,下载为 pdf 放到知识库文件夹。
演示
问题:赵某为某市小学教师。在执教期间,曾有学生家长于2019年1月以赵某非礼其女儿为由向学校举报,赵某因此写下书面检讨,保证不再发生此类事件。然而,2019年1月至2022年6月以来,赵某利用教学之便,在课间活动及补课期间,多次对5名女学生进行猥亵。你作为法官审理该案件,该如何审判?
LLM 回答
作为法官,审理此类案件时,必须严格遵守法律程序,确保公正、公平地处理案件,同时保护受害者的权益。以下是审理此类案件时可能采取的步骤和考虑因素:
-
案件事实的审查
- 证据收集:首先,需要审查所有相关证据,包括受害者的陈述、目击证人的证言、学校的记录、赵某的书面检讨等。确保所有证据的真实性和合法性。
- 受害者的陈述:听取受害者的陈述,了解她们的经历和感受。确保她们在陈述过程中得到充分的尊重和保护,避免二次伤害。
- 赵某的供述:听取赵某的供述,了解他对指控的回应和辩解。确保他在法律程序中的权利得到保障。
-
法律适用
- 刑法相关规定:根据《中华人民共和国刑法》第二百三十七条,猥亵儿童罪是指以暴力、胁迫或其他方法猥亵儿童的行为。赵某的行为涉嫌构成猥亵儿童罪。
- 量刑标准:根据刑法规定,猥亵儿童罪的量刑标准较为严厉,通常处五年以下有期徒刑或者拘役。如果情节特别恶劣,可能处五年以上有期徒刑。
-
情节认定
- 多次作案:赵某在2019年1月至2022年6月期间多次对5名女学生进行猥亵,属于多次作案,情节恶劣。
- 利用职务之便:赵某作为教师,利用教学之便对未成年人实施猥亵,属于利用职务之便实施犯罪,应当从重处罚。
- 受害者年龄:受害者均为未成年人,尤其是小学生,属于特别需要保护的群体,赵某的行为对她们的身心健康造成了严重伤害。
-
判决
- 罪名成立:根据证据和法律规定,认定赵某犯有猥亵儿童罪。
- 量刑:鉴于赵某多次作案、利用职务之便、受害者均为未成年人等情节,应当从重处罚。根据刑法相关规定,判处赵某五年以上有期徒刑。
- 附加处罚:根据《中华人民共和国刑法》第三十七条,可以附加剥夺赵某从事教育工作的资格,禁止其在一定期限内从事与未成年人相关的职业。
-
受害者保护
- 心理辅导:为受害者提供必要的心理辅导和支持,帮助她们走出阴影,恢复正常生活。
- 隐私保护:在案件审理过程中,严格保护受害者的隐私,避免她们的姓名、身份等信息被公开。
-
社会影响
- 警示教育:通过此案的审理和判决,向社会传递严厉打击侵害未成年人权益行为的信号,警示其他潜在犯罪分子。
- 学校责任:建议学校加强师德师风建设,完善监督机制,防止类似事件再次发生。
-
法律程序
- 上诉权:赵某有权在法定期限内对判决提出上诉,法院将依法处理其上诉请求。
总结:作为法官,应当依法公正审理此案,确保赵某受到应有的法律制裁,同时保护受害者的权益,维护社会的公平正义。通过此案的审理,向社会传递出对侵害未成年人权益行为的零容忍态度,推动社会对未成年人保护的进一步重视。
LLM with RAG 回答
根据提供的法律库信息,结合案件事实,赵某的行为已构成猥亵儿童罪。以下是审判分析及判决建议:
案件事实分析
- 主体身份:赵某为小学教师,具有特殊的教育职责和监护义务,其行为不仅违反职业道德,还严重侵害未成年人权益。
- 行为性质:赵某利用教学便利,多次对5名女学生实施猥亵,且部分行为发生在公共场所(如课间活动及补课期间),情节恶劣。
- 主观恶性:赵某曾因类似行为被举报,并写下书面检讨,但其不思悔改,继续实施犯罪行为,主观恶性较大。
- 社会危害性:赵某的行为严重破坏教学秩序,对被害学生及其家庭造成严重的身心伤害,社会危害性极大。
法律适用 根据《中华人民共和国刑法》第二百三十七条关于猥亵儿童罪的规定:
- 以暴力、胁迫或其他方法猥亵儿童的,处五年以下有期徒刑或者拘役。
- 聚众或者在公共场所当众猥亵儿童的,处五年以上有期徒刑。
赵某的行为符合以下加重情节:
- 多次实施猥亵:赵某在2019年1月至2022年6月期间多次对5名女学生实施猥亵。
- 利用教师身份:赵某利用教学便利实施犯罪,属于利用特殊身份侵害未成年人权益。
- 公共场所当众实施:部分行为发生在课间活动及补课期间,属于公共场所当众实施猥亵。
- 曾因类似行为被举报:赵某曾因非礼学生被举报并写下书面检讨,但仍继续实施犯罪行为,主观恶性较大。
判决建议
- 罪名认定 :赵某的行为构成猥亵儿童罪,且情节严重,符合加重处罚的情形。
- 量刑建议 :
- 根据法律规定及类似案例(如祁某案),赵某的行为应判处五年以上有期徒刑。
- 鉴于赵某曾因类似行为被举报仍不思悔改,主观恶性较大,建议从重处罚。
- 附加处罚 :
- 禁止赵某从事与未成年人相关的职业(如教师、培训师等)。
- 对被害学生及其家庭进行心理疏导及必要的经济赔偿。
判决结果 综上所述,判决如下:
- 赵某犯猥亵儿童罪 ,判处有期徒刑七年。
- 禁止赵某从事与未成年人相关的职业,期限为终身。
- 责令赵某赔偿被害学生及其家庭的经济损失,并承担相应的心理治疗费用。
判决依据
- 《中华人民共和国刑法》第二百三十七条。
- 最高人民法院关于保护未成年人权益的相关司法解释及典型案例。
以上判决旨在严惩犯罪行为,保护未成年人合法权益,维护社会公平正义。
评价
该问题由祁某案改编而成。
LLM 说的很好,但不轻易下论断。
LLM + RAG 审判结果与祁某的案例审判结果基本一致,如加重情节 和审判结果,并且引用了该案件(如祁某案)👍👍👍
启动项目
本项目是一个基于大模型的法律问答系统,LangChain 作为开发框架, DeepSeek 作为 LLM 大模型,智谱的 Embedding-3 作为 Embedding 模型。
项目结构
bash
.
├── README.md # 项目说明文档
├── chroma # 向量存储目录
├── law_data # 知识库目录
├── main.py # 主程序
├── requirements.txt # 依赖
├── vector.py # 基于 Chroma 的向量类
└── zhipuai_embedding.py # 智谱 AI 的 Embedding 类
核心代码
主程序,使用 LangChain 集成 rag_chain。
python
# main.py
import os
from langchain_core.runnables import RunnableParallel, RunnablePassthrough
from langchain_openai.chat_models.base import BaseChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
from vector import LawVectordb
if __name__ == '__main__':
print("欢迎体验 LLM + RAG 在法律领域应用")
# 重要参数,可自行修改
# DeepSeek LLM
TEMPERATURE = 0.7
MAX_TOKENS = 1024
# Vectordb
DATA_DIR = "./law_data"
PERSIST_DIR = "./chroma"
CHUNK_SIZE = 50
OVERLAP = 10
llm = BaseChatOpenAI(
model='deepseek-chat',
openai_api_key=os.environ["DEEPSEEK_API_KEY"],
openai_api_base='https://api.deepseek.com',
temperature=TEMPERATURE,
max_tokens=MAX_TOKENS
)
lawVectordb = LawVectordb(data_directory=DATA_DIR, persist_directory=PERSIST_DIR,
chunk_size=CHUNK_SIZE, overlap=OVERLAP)
db = lawVectordb.makeVectordb()
retriever = db.as_retriever()
output_parser = StrOutputParser()
template = """你是一名法官,可以帮助我审判法律案件。你得到法律库:
{context}
问题:{question}
"""
prompt = ChatPromptTemplate.from_template(template)
setup_and_retrieval = RunnableParallel(
{"context": retriever, "question": RunnablePassthrough()}
)
rag_chain = setup_and_retrieval | prompt | llm | output_parser
questions = ["赵某为某市小学教师。在执教期间,曾有学生家长于2019年1月以赵某非礼其女儿为由向学校举报,赵某因此写下书面检讨,保证不再发生此类事件。然而,2019年1月至2022年6月以来,赵某利用教学之便,在课间活动及补课期间,多次对5名女学生进行猥亵。你作为法官审理该案件,该如何审判?"]
for q in questions:
print("*" * 50)
print(f"问题:{q}")
print(f"LLM 回答:{llm.invoke(q).content}")
print("-" * 50)
print(f"LLM with RAG :{rag_chain.invoke(q)}")
LawVectordb 类,加载准备好的 pdf 文件,并转换为 Embedding,作为检索增强的数据库。
python
# vector.py
import os
from langchain_community.document_loaders import PyMuPDFLoader
from langchain_community.document_loaders import UnstructuredMarkdownLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from zhipuai_embedding import ZhipuAIEmbeddings
from langchain_chroma import Chroma
class LawVectordb:
def __init__(self, data_directory="./law_data", persist_directory="./chroma", chunk_size=20, overlap=5):
self.data_directory = data_directory
self.persist_directory = persist_directory
self.chunk_size = chunk_size
self.overlap = overlap
def makeVectordb(self):
embedding = ZhipuAIEmbeddings()
if os.listdir(self.persist_directory):
# 持久库是非空的,直接加载
vectordb = Chroma(
embedding_function=embedding,
persist_directory=self.persist_directory
)
else:
loaders = []
paths = os.listdir(self.data_directory)
for path in paths:
relative_path = os.path.join(self.data_directory, path)
file_type = path.split(".")[-1]
if file_type == "pdf":
loaders.append(PyMuPDFLoader(relative_path))
elif file_type == "md":
loaders.append(UnstructuredMarkdownLoader(relative_path))
texts = []
for loader in loaders:
pdf_documents = loader.load()
for page in pdf_documents:
page.page_content = page.page_content.replace("\n", "")
print(pdf_documents)
texts.extend(pdf_documents)
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=self.chunk_size,
chunk_overlap=self.overlap,
)
split_docs = text_splitter.split_documents(texts)
# 加载文档到chrome向量库中,并持久化,vectordb = persist + docs
vectordb = Chroma.from_documents(
documents=split_docs,
embedding=embedding,
persist_directory=self.persist_directory
)
return vectordb
def reloadVectordb(self, chunk_size=50, overlap=10):
files = os.listdir(self.data_directory)
if len(files) != 0:
for file in files:
os.remove(os.path.join(self.data_directory, file))
self.chunk_size = chunk_size
self.overlap = overlap
return self.makeVectordb()
前置准备
克隆项目
shell
# GitHub
git clone https://github.com/xiaolinstar/llm-law.git
# git clone [email protected]:xiaolinstar/llm-law.git
# Gitee
# git clone https://gitee.com/xingxiaolin/llm-law.git
# git clone [email protected]:xingxiaolin/llm-law.git
进入目录
shell
cd llm-law
使用 Anaconda 安装虚拟环境,使用 pip 安装依赖
shell
# 1. 创建 conda 环境
conda create -n llm-law python=3.10
# 2. 激活 conda 环境
conda activate llm-law
# 3. 安装项目依赖
pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
DeepSeek 和 智谱 AI 的 API 密钥需要在环境变量中配置。
请自行到官网付费以获取商业服务,Token 使用量极少,最低充值即可。
一次性的:
shell
export OPENAI_API_KEY="deepseek-api-xxx"
export ZHIPUAI_API_KEY="zhipu-api-xxx"
永久有效的:
shell
echo "export OPENAI_API_KEY="deepseek-api-xxx"" >> ~/.bashrc
echo "export ZHIPUAI_API_KEY="zhipu-api-xxx"" >> ~/.bashrc
.bashrc
根据你的 shell 情况可以是 .zshrc
或其他。
开始
运行主程序
shell
python main.py
修改问题:main.py
中的 questions
变量,代码第 50 行
ini
questions = ["赵某为某市小学教师。在执教期间,曾有学生家长于2019年1月以赵某非礼其女儿为由向学校举报,赵某因此写下书面检讨,保证不再发生此类事件。然而,2019年1月至2022年6月以来,赵某利用教学之便,在课间活动及补课期间,多次对5名女学生进行猥亵。你作为法官审理该案件,该如何审判?"]
自定义知识库
RAG 基于向量检索,需要有知识库。
知识库的目录为 ./law_data
,本项目代码中支持 PDF 和 Markdown 格式。
重要参数可在 main.py
中修改:
ini
# 重要参数,可自行修改
# DeepSeek LLM
TEMPERATURE = 0.7
MAX_TOKENS = 1024
# Vectordb
DATA_DIR = "./law_data"
PERSIST_DIR = "./chroma"
CHUNK_SIZE = 20
OVERLAP = 5
如果您在体验之后,进一步尝试:
- 修改参数(CHUNK_SIZE 或 OVERLAP)
- 更新知识库
进行以下操作即可:
- 修改
main.py
中的参数 - 更新
./law_data
目录下的文件 - 删除
./chroma
目录下的所有文件
然后重新运行 main.py
即可。
下一步工作
在领域应用中有一些需要细化与研究步骤,包括但不限于:
- 数据处理:格式化、删除空格、分隔符等
- 增量更新:知识库是不断丰富的,应当支持增量更新知识库
- 开发交互式应用:在供用户使用时,需提供好的交互式工具,如 Web 应用或手机 App
- 检验 RAG 效果:参数调优,应用效果评价,只有能用、好用的 AI 才能真正提高生产力。
总结
本文介绍了大语言模型在法律领域的应用,基本理论为:检索增强生成(RAG)。
该项目虽然以法律案件为应用场景,但可以发现在技术实现上是弱耦合关系,认真读完本篇文章,并亲手实践一番,将进一步理解 LLM + RAG 领域应用开发。
关注微信公众号,获取运维资讯
如果此篇文章对你有所帮助,感谢你的点赞 与收藏,也欢迎在评论区友好交流。
微信搜索关注公众号:持续运维
参考
-
向量数据库技术原理及常见向量数据库介绍 cloud.tencent.com/developer/a...
-
维基百科:大型语言模型 zh.wikipedia.org/wiki/%E5%A4...
-
LangChain github.com/langchain-a...
-
LangChain 自定义 智谱 AI Embedding类 github.com/datawhalech...
-
DeepSeek API 文档 api-docs.deepseek.com/zh-cn/
-
智谱大模型API Keys bigmodel.cn/usercenter/...
-
面向法律场景的大模型 RAG 检索增强解决方案 developer.aliyun.com/article/164...
-
Anaconda anaconda.org/anaconda/co...
-
保护未成年人权益十大优秀案例 www.court.gov.cn/zixun/xiang...