文章目录
-
- \1. RAG
- \2. 构建流程
-
- 2.1 文档加载与切分
- 2.2 传统检索引擎
- 2.3 LLM接口封装
- 2.4 构建prompt
- \3. 向量检索
- \4. 向量数据库
- \5. 基于向量检索的RAG
- \6. 进阶知识
-
- 6.1 文本分割粒度
- 6.2 检索后再排序
- 6.3 测试
1. RAG
RAG(Retrieval Augmented Generation),通过检索获取一些信息,传给大模型,提高回复的准确性。
一般流程:
- 离线步骤:文档加载切片 -> 向量化 -> 存入向量数据库
- 在线步骤:用户提问 -> 向量化 ->检索 -> 组装提示词 -> LLM -> 输出回复
2. 构建流程
相关环境
代码语言:javascript
复制
pip install pdfminer.six # pdf解析
pip install openai -U # openai-1.3.7
2.1 文档加载与切分
代码语言:javascript
复制
import pathlib
def extract_text_from_pdf(filename, page_numbers=None, min_line_length=1):
'''从 PDF 文件中(按指定页码)提取文字'''
paragraphs = []
buffer = ''
full_text = ''
# 提取全部文本
for i, page_layout in enumerate(extract_pages(filename)):
# 如果指定了页码范围,跳过范围外的页
if page_numbers is not None and i not in page_numbers:
continue
for element in page_layout:
if isinstance(element, LTTextContainer):
full_text += element.get_text() + '\n'
# 按空行分隔,将文本重新组织成段落
lines = full_text.split('\n')
for text in lines:
if len(text) >= min_line_length:
buffer += (' ' + text) if not text.endswith('-') else text.strip('-')
elif buffer:
paragraphs.append(buffer)
buffer = ''
if buffer:
paragraphs.append(buffer)
return paragraphs
代码语言:javascript
复制
paragraphs = extract_text_from_pdf(pathlib.Path(__file__).parent.absolute() / "llama2.pdf", min_line_length=10)
2.2 传统检索引擎
- 安装 ElasticSearch
代码语言:javascript
复制
pip install elasticsearch8
pip install nltk
代码语言:javascript
复制
from elasticsearch8 import Elasticsearch, helpers
from nltk.stem import PorterStemmer
from nltk.tokenize import word_tokenize
from nltk.corpus import stopwords
import nltk
import re
import warnings
warnings.simplefilter("ignore") #屏蔽 ES 的一些Warnings
nltk.download('punkt') # 英文切词、词根、切句等方法
nltk.download('stopwords') # 英文停用词库
def to_keywords(input_string):
'''(英文)文本只保留关键字'''
# 使用正则表达式替换所有非字母数字的字符为空格
no_symbols = re.sub(r'[^a-zA-Z0-9\s]', ' ', input_string)
word_tokens = word_tokenize(no_symbols)
stop_words = set(stopwords.words('english'))
ps = PorterStemmer