AI大模型 图书智能检索系统:融合 RAG 技术的文学智能问答解决方案
·
前言
在数字时代,如何让传统文学作品焕发新的生命力,为读者提供更智能、更深入的阅读体验?由宁渡 allen 开发的 “图书智能检索系统” 给出了创新答案。该系统基于检索增强生成(RAG)技术,将传统文学作品与现代 AI 技术深度融合,构建了一套完整的智能化文学问答体系,尤其在古典文学如《红楼梦》的深度解析方面展现出独特优势
项目概述:技术与文学的跨界融合
图书智能检索系统的核心目标是打破传统文本检索的局限,通过 AI 技术实现对文学作品的深度理解与智能问答。
效果

核心技术栈
- 核心框架: Python 3.13
- 编辑器: PyCharm
- AI 模型: DeepSeek API
- 向量化: TF-IDF + scikit-learn
- 中文分词: jieba
- 文档处理: 自定义文本分块算法
- 缓存机制: pickle 序列化
- 可视化界面: streamlit
系统核心流程
用户问题 → 文本预处理 → 向量化 → 相似度检索 → 上下文构建 → AI生成答案
系统形成从问题输入到精准回答的完整闭环,为文学爱好者、研究者提供专业级的文本解析服务。
核心架构:SmartLibRAG 类的设计与实现
系统的核心功能集中于SmartLibRAG类,其设计体现了模块化、可扩展的架构思想,关键核心代码如下:
1. 初始化设计
def __init__(self, api_key: str, docs_dir: str = "docs"):
# 依赖注入API密钥,便于测试和部署
self.api_key = api_key
# 路径抽象处理
self.docs_dir = Path(docs_dir)
# 预设缓存目录
self.cache_dir = Path(".cache")
self.cache_dir.mkdir(exist_ok=True)
# 组件分离管理
self.vectorizer = None
self.vector_index = None
self.documents = []
self.chunks = []
# 加载停用词
self.stopwords = {'的', '了', '在', '是', '我', '有', '和', '就', '不', '人', '都', '一', '一个', '上', '也', '很', '到', '说', '要', '去', '你', '会', '着', '没有', '看', '好', '自己', '这'}
2.文档加载策略
def load_documents(self) -> None:
"""使用生成器模式遍历文件,支持异常处理"""
if not self.docs_dir.exists():
self.docs_dir.mkdir(exist_ok=True)
return
# 生成器遍历文档目录
for file_path in self.docs_dir.glob("*.txt"):
try:
with open(file_path, "r", encoding="utf-8") as f:
content = f.read()
# 结构化存储元信息
self.documents.append({
"filename": file_path.name,
"path": str(file_path),
"content": content
})
except Exception as e:
print(f"加载文件 {file_path.name} 失败: {str(e)}")
continue
3. 智能文本分块算法
def split_text_into_chunks(self, text: str, chunk_size: int = 300, overlap: int = 50):
"""基于语义边界的文本分块,保持语义完整性"""
# 按中文标点分句
sentences = re.split(r'([。!?;:""()【】《》、])', text)
# 重组句子(保留标点)
sentences = [''.join(pair) for pair in zip(sentences[::2], sentences[1::2])] if len(sentences) > 1 else sentences
chunks = []
current_chunk = ""
for sentence in sentences:
if len(current_chunk) + len(sentence) <= chunk_size:
current_chunk += sentence
else:
if current_chunk:
chunks.append(current_chunk.strip())
# 动态调整:如果单句超长,直接作为一个块
current_chunk = sentence if len(sentence) <= chunk_size else sentence[:chunk_size]
if current_chunk:
chunks.append(current_chunk.strip())
# 可扩展重叠逻辑
if len(chunks) > 1 and overlap > 0:
# 示例重叠实现(当前未启用)
pass
return chunks
4. 中文 NLP 处理
def chinese_tokenizer(self, text):
"""中文分词与过滤:分词→长度过滤→停用词过滤→标点过滤"""
import jieba
# jieba分词
words = jieba.cut(text)
filtered_words = []
for word in words:
# 多重过滤逻辑
if (word and
len(word) > 1 and # 过滤单字符
word not in self.stopwords and # 过滤停用词
not word.isspace() and # 过滤空白字符
not all(char in ',。!?;:""()【】《》、' for char in word)): # 过滤纯标点
filtered_words.append(word)
return filtered_words
5. 向量索引构建(TF-IDF)
核心公式
"""
TF-IDF = 词频(TF) × 逆文档频率(IDF)
TF = 某个词在文章中的出现次数 / 文章总词数
IDF = log(语料库的文档总数 / 包含该词的文档数 + 1)
"""
示例代码
def build_vector_index(self) -> None:
"""构建TF-IDF向量索引,支持缓存恢复"""
from sklearn.feature_extraction.text import TfidfVectorizer
import numpy as np
# 检查缓存
cache_file = self.cache_dir / "vector_index.pkl"
if cache_file.exists():
with open(cache_file, "rb") as f:
cache_data = pickle.load(f)
self.vectorizer = TfidfVectorizer(
tokenizer=self.chinese_tokenizer,
vocabulary=cache_data['vocabulary']
)
self.vectorizer.idf_ = cache_data['idf']
self.vector_index = cache_data['index']
return
# 构建向量器
self.vectorizer = TfidfVectorizer(
tokenizer=self.chinese_tokenizer,
max_features=5000, # 控制词汇表大小
ngram_range=(1, 2), # 包含单词和双词组合
min_df=1, # 过滤低频词
max_df=0.95 # 过滤高频词
)
# 训练并生成向量索引
chunk_texts = [chunk['content'] for chunk in self.chunks]
self.vector_index = self.vectorizer.fit_transform(chunk_texts)
# 缓存保存
cache_data = {
'vocabulary': self.vectorizer.vocabulary_,
'idf': self.vectorizer.idf_,
'index': self.vector_index
}
with open(cache_file, "wb") as f:
pickle.dump(cache_data, f)
# TF-IDF示例演示
tf = TfidfVectorizer(norm='l2')
train = ["Chinese Beijing Chinese", "Chinese Chinese shanghai", "Chinese Macao", "Tokyo Japan, Chinese"]
tf.fit(train)
print(tf.get_feature_names_out()) # 输出:['beijing' 'chinese' 'japan' 'macao' 'shanghai' 'tokyo']
test = ["Chinese Chinese Chinese Tokyo Japan"]
tf_fit = tf.transform(test)
print(tf_fit.toarray()) # 输出:[[0. 0.7420575 0.4739993 0. 0. 0.4739993]]
6. 检索算法优化
def search_relevant_chunks(self, query: str, top_k: int = 10, similarity_threshold: float = 0.01):
"""优化检索:阈值过滤→有效结果排序→数量控制"""
import numpy as np
from sklearn.metrics.pairwise import cosine_similarity
# query向量化
query_vec = self.vectorizer.transform([query])
# 计算相似度
similarities = cosine_similarity(query_vec, self.vector_index)[0]
# 性能优化:只处理有效结果
valid_indices = np.where(similarities > similarity_threshold)[0]
# 降序排序
sorted_indices = valid_indices[np.argsort(similarities[valid_indices])[::-1]]
# 取top_k结果
top_indices = sorted_indices[:top_k]
results = []
for idx in top_indices:
results.append({
"content": self.chunks[idx]['content'],
"source": self.chunks[idx]['source'],
"similarity": float(similarities[idx])
})
return results
7. AI 生成模块(Prompt 工程 + 错误处理)
系统提示词
SYSTEM_PROMPT = """
# Role: 红楼梦研究专家
## Profile
- language: 中文
- description: 精通《红楼梦》文本及红学研究,能够深入解析作品的人物、情节、诗词及文化内涵
- background: 多年从事《红楼梦》研究与教学,参与过多项红学课题研究
- personality: 严谨细致,富有文人气质,善于引经据典
- expertise: 文本分析、人物研究、诗词鉴赏、文化解读
- target_audience: 红学爱好者、文学研究者、学生群体
## Skills
1. 文本解析能力:情节梳理、细节把握、人物分析、诗词解读
2. 学术研究能力:文献考证、文化阐释、比较研究、版本鉴别
## Rules
1. 回答原则:基于文本、严谨准确、深度解析、客观公正
2. 行为准则:引经据典、语言典雅、层次分明、深入浅出
3. 限制条件:不涉争议、不妄评续作、不越文本、不代作者
## Workflows
- 步骤 1: 仔细理解用户问题,明确询问重点
- 步骤 2: 检索相关文本段落,确认信息准确性
- 步骤 3: 组织回答内容,适当引用原文
- 步骤 4: 以典雅文风呈现完整解答
## Initialization
作为红楼梦研究专家,你必须遵守上述Rules,按照Workflows执行任务。
"""
生成函数
def generate_answer(self, query: str, context_chunks: List[Dict]) -> str:
"""基于上下文生成专业回答,包含错误处理"""
import requests
# 构建上下文
context_text = "\n\n".join([f"【参考片段】{chunk['content']}" for chunk in context_chunks])
user_prompt = f"用户问题:{query}\n\n参考上下文:{context_text}\n\n请基于上述参考上下文,以红楼梦研究专家的身份回答用户问题,要求引经据典、语言典雅、准确严谨。"
try:
# 调用DeepSeek API
response = requests.post(
"https://api.deepseek.com/v1/chat/completions",
headers={
"Content-Type": "application/json",
"Authorization": f"Bearer {self.api_key}"
},
json={
"model": "deepseek-chat",
"messages": [
{"role": "system", "content": SYSTEM_PROMPT},
{"role": "user", "content": user_prompt}
],
"temperature": 0.3
}
)
response.raise_for_status()
return response.json()["choices"][0]["message"]["content"]
except Exception as e:
error_type = type(e).__name__
error_details = str(e) if str(e) else "未知错误"
return f"生成答案时出错: {error_type} - {error_details}"
8. 统一问答接口
def ask(self, question: str, top_k: int = 10, similarity_threshold: float = 0.01) -> Dict:
"""统一问答接口:参数可配置、结构化返回、来源追踪"""
# 检索相关片段
relevant_chunks = self.search_relevant_chunks(question, top_k, similarity_threshold)
# 生成答案
answer = self.generate_answer(question, relevant_chunks)
# 构建来源信息
sources = [
{
"source": chunk["source"],
"similarity": chunk["similarity"],
"content_preview": chunk["content"][:100] + "..." if len(chunk["content"]) > 100 else chunk["content"]
}
for chunk in relevant_chunks
]
# 结构化返回
return {
'question': question,
'answer': answer,
'sources': sources
}
部署与使用
1.环境配置
# 根目录创建.env文件
DEEPSEEK_API_KEY=your_api_key_here
2. 初始化流程
from smart_lib_rag import SmartLibRAG
import os
from dotenv import load_dotenv
# 加载环境变量
load_dotenv()
api_key = os.getenv("DEEPSEEK_API_KEY")
# 初始化系统
rag = SmartLibRAG(api_key=api_key)
rag.initialize() # 一键初始化所有组件(加载文档→分块→构建向量索引)
3.streamlit 可视化界面
页面配置
import streamlit as st
# 页面基础配置
st.set_page_config(
page_title="图书智能检索系统",
page_icon="📚",
layout="wide",
initial_sidebar_state="expanded"
)
自定义样式
# 注入自定义CSS
st.markdown("""
<style>
@import url('https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@400;600;700&display=swap');
.main-header {
font-size: 3rem;
background: linear-gradient(135deg, #8B4513, #CD853F);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
text-align: center;
margin-bottom: 2rem;
font-weight: 700;
font-family: 'Noto Serif SC', serif;
}
.chat-message {
padding: 1.2rem;
border-radius: 1rem;
margin-bottom: 1rem;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}
.user-message {
background: linear-gradient(135deg, #e3f2fd, #bbdefb);
border-left: 4px solid #2196f3;
margin-left: 2rem;
}
.assistant-message {
background: linear-gradient(135deg, #fff8e1, #ffecb3);
border-left: 4px solid #8B4513;
margin-right: 2rem;
}
.source-info {
background: linear-gradient(135deg, #f3e5f5, #e1bee7);
padding: 0.8rem;
border-radius: 0.8rem;
margin-top: 0.8rem;
font-size: 0.9rem;
}
</style>
""", unsafe_allow_html=True)
聊天消息显示函数
def display_chat_message(role, content, sources=None, typing=False):
"""显示聊天消息,支持来源展开"""
if role == "user":
st.markdown(f"""
<div class="chat-message user-message">
<strong>🙋♀️ 您:</strong> {content}
</div>
""", unsafe_allow_html=True)
else:
typing_indicator = '<span class="typing-indicator">💭</span>' if typing else '🤖'
st.markdown(f"""
<div class="chat-message assistant-message">
<strong>{typing_indicator} 红楼梦助手:</strong> {content}
</div>
""", unsafe_allow_html=True)
if sources:
with st.expander(f"📖 参考文档片段 ({len(sources)}个)", expanded=False):
for i, source in enumerate(sources, 1):
# 相似度颜色标记
similarity_color = "#4caf50" if source['similarity'] > 0.5 else "#ff9800" if source['similarity'] > 0.3 else "#f44336"
st.markdown(f"""
<div class="source-info">
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 0.5rem;">
<strong>📄 片段 {i}: {source['source']}</strong>
<span style="background: {similarity_color}; color: white; padding: 0.2rem 0.5rem; border-radius: 1rem; font-size: 0.8rem;">
相似度: {source['similarity']:.3f}
</span>
</div>
<div style="background: rgba(255,255,255,0.8); padding: 0.5rem; border-radius: 0.5rem; border-left: 3px solid {similarity_color};">
<em>📝 内容预览:</em><br>
{source['content_preview']}
</div>
</div>
""", unsafe_allow_html=True)
性能优化与扩展方向
性能优化建议
-
缓存策略优化:实现文件变更检测、添加内存缓存层、集成 Redis 外部缓存
-
检索算法优化:引入 Faiss 专业向量检索库、实现多路召回策略、添加查询扩展机制
-
并发处理:支持异步处理、实现请求队列管理、多进程部署
扩展方向
-
多模态支持:图片内容理解、音频问答功能
-
知识图谱集成:构建人物关系图谱、情节时间线可视化
-
个性化推荐:用户兴趣建模、智能问题推荐
总结
图书智能检索系统以 RAG 技术为核心,通过精巧的架构设计与细致的工程实现,打通了传统文学文本与现代 AI 的连接通道。其核心代码的模块化设计既保证了当前功能的稳定运行,也为未来扩展预留了充足空间,为文学智能分析领域提供了可复用、可扩展的解决方案。
文档资料

另外更多大模型面试题

更多推荐

所有评论(0)