【项目实训3】RAG多维优化工程
—— written by Unalome (2025.04.15-16)
一. 引入jieba分词提升Haystack-RAG中文后续检索精度
通过替换Haystack默认的英文分词工具,结合jieba的精确模式和搜索引擎模式对中文文本进行切分,同时过滤停用词并加载领域自定义词典,显著提升了文档预处理的语义准确性。这种改进使检索模型能更精准地捕捉中文词汇的边界和专业术语,减少因分词不当导致的语义偏差,从而在检索中提高匹配效率,尤其在垂直领域场景下效果更为明显。
import jieba
# === 中文处理函数 ===
def chinese_text_processor(text: str) -> str:
return " ".join(jieba.lcut(text))
# === 预处理 ===
processed_docs = []
document_cleaner = DocumentCleaner()
text_splitter = DocumentSplitter(
split_by="word",
split_length=200,
split_overlap=20
)
for doc_text in raw_docs:
# 创建文档对象
doc = Document(content=doc_text)
# 清理文档
cleaned_result = document_cleaner.run(documents=[doc])
cleaned_docs = cleaned_result["documents"]
# 处理每个清理后的文档
for cleaned_doc in cleaned_docs:
# 中文分词处理
cleaned_doc.content = chinese_text_processor(cleaned_doc.content)
# 文档分割
split_result = text_splitter.run(documents=[cleaned_doc])
processed_docs.extend(split_result["documents"])
document_store.write_documents(processed_docs)
二、修改提示词以限制输出结果范围
针对输出结果范围的限制,通过在生成提示词中加入显式约束指令(禁止编造信息)和结构化输出格式,有效约束了模型的生成行为。这不仅减少了模型因自由生成导致的幻觉问题,还通过格式化响应提升了结果的可解析性,使其更适配后续自动化处理流程,同时缩短了生成时间,降低了计算资源的消耗。
template = [
ChatMessage.from_user(
"""
{% if documents|length == 0 %}
该知识尚未被学习
{% else %}
Answer the question based on the context:
{% for document in documents %}
{{ document.content }}
{% endfor %}
Question: {{ query }}
{% endif %}
"""
)
]
prompt_builder = ChatPromptBuilder(template=template)
三、使用流式输出优化检索体验
流式输出的优化则通过分块生成和实时传输技术实现,将模型生成的内容拆分为多个片段逐步返回,并在前端通过SSE实时渲染(开发中)。这种方式让用户无需等待完整结果即可获取初步信息,显著降低了感知延迟,尤其适用于长文本生成场景。
同时,后端通过缓存部分生成结果平衡实时性与稳定性,既提升了用户体验,又避免了服务阻塞问题,实现了交互友好性与资源利用率的双重优化。
首先定义回调函数
from haystack.dataclasses import StreamingChunk
# 定义流式回调处理函数
def streaming_callback(chunk: StreamingChunk):
print(chunk.content, end="", flush=True)
# 创建生成器时配置回调
chat_generator = OpenAIChatGenerator(
# model="gpt-4o-mini",
model="DeepSeek-R1",
api_base_url=os.environ["OPENAI_API_BASE"],
generation_kwargs={
"temperature": 0.0,
"stream": True
},
streaming_callback=streaming_callback # 异步回调
)
并修改输出逻辑
while True:
query = input("\n你的问题: ")
if query.lower() in ["exit", "quit"]:
break
processed_query = chinese_text_processor(query)
print("\n--- 流式输出 ---")
try:
_ = pipeline.run(
data={
"retriever": {"query": processed_query},
"prompt_builder": {"query": query},
}
)
except Exception as e:
print(f"处理出错: {str(e)}")
finally:
print("\n--- 输出完成 ---")
四、使用chromadb实现长期存储和加速检索
基于Haystack与ChromaDB构建高效可靠的RAG文档存储与检索架构,通过ChromaDocumentStore实现持久化存储,结合动态滑动窗口分块、中文分词优化及实时去重算法,形成多阶段智能预处理流水线。采用余弦相似度计算,实现了高维向量空间快速检索响应。
自定义ChromaRetriever组件实现灵活的top-k检索与元数据过滤,结合按需加载和内存缓存策略,为大规模知识库应用提供了高效且经济的技术支持。
# 1. 创建Chroma文档存储(持久化到本地)
chroma_store = ChromaDocumentStore(
persist_path="chroma_db", # 本地存储路径
distance_function="cosine",
# index="hnsw",
# persist=True
# embedding_function=ef
)
# 原始文档(首次运行时写入)
raw_docs = [
"***********"
]
# 检查是否已存在数据(避免重复写入)
if chroma_store.count_documents() == 0:
processed_docs = []
document_cleaner = DocumentCleaner()
text_splitter = DocumentSplitter(
split_by="word",
split_length=200,
split_overlap=50,
split_threshold=0.5
)
text_splitter.warm_up()
for doc_text in raw_docs:
doc = Document(content=doc_text)
cleaned_result = document_cleaner.run(documents=[doc])
cleaned_docs = cleaned_result["documents"]
for cleaned_doc in cleaned_docs:
# 中文分词处理
cleaned_doc.content = chinese_text_processor(cleaned_doc.content)
# 内容去重
word_list = cleaned_doc.content.split()
unique_words = []
seen = set()
for word in word_list:
if word not in seen:
seen.add(word)
unique_words.append(word)
cleaned_doc.content = " ".join(unique_words)
split_result = text_splitter.run(documents=[cleaned_doc])
processed_docs.extend(split_result["documents"])
chroma_store.write_documents(processed_docs)
# 2. 自定义Chroma检索器
@component
class ChromaRetriever:
def __init__(self, document_store: ChromaDocumentStore, top_k: int = 10):
self.document_store = document_store
self.top_k = top_k
@component.output_types(documents=List[Document])
def run(self, query: str, filters: Optional[Dict] = None):
results = self.document_store.search(
queries=[query], top_k=self.top_k, filters=filters)
return {"documents": results[0]}
# 初始化检索器
retriever = ChromaRetriever(document_store=chroma_store, top_k=10)
五、下一步开发目标
(1)修改文档处理机制,加入增量更新功能,目前的数据库只支持一次性更新。
(2)引入混合检索机制,进一步提升复杂场景下的语义理解能力与数据维护效率。(optional)
(3)前端工程:使用Cherry Studio作为输出媒介,将生成的流式答案通过该媒介展示给用户
(4)数据库工程:接入山东大学数据中台,获取准数据集

浙公网安备 33010602011771号