Skip to content

Qihang7/WearRAG

Repository files navigation

RAGProject — 智能客服 RAG 系统

基于 LangChain + ChromaDB + 阿里云 DashScope 的检索增强生成(RAG)智能客服系统,面向服装/时尚零售场景,提供知识库管理、多轮对话问答和流式输出的完整解决方案。


目录


项目概述

本系统将服装领域的知识文档(尺码推荐、洗涤养护、颜色选择)向量化存入 ChromaDB,当用户提问时,通过语义检索召回最相关的文档片段,结合对话历史,由 Qwen3-Max 大模型生成基于参考资料的精准回复。

核心特性:

  • 文档摄取:支持上传 .txt 知识文档,自动分块、向量化、去重存储
  • 语义检索:基于 ChromaDB + HNSW 索引的高效向量相似度搜索
  • 上下文生成:将检索结果作为参考上下文注入 LLM,生成高质量的领域回答
  • 多轮对话:基于文件的会话历史持久化,支持上下文连续的多轮问答
  • 流式输出:前端实时流式展示 LLM 生成的回答,提升交互体验
  • 两套应用:独立的知识库管理端 + 用户问答端,职责清晰

技术架构

┌──────────────────────────────────────────────────────────────────────┐
│                          RAGProject                                   │
│                                                                       │
│  ┌──────────────────────────┐    ┌──────────────────────────────┐    │
│  │  app_file_uploader.py    │    │        app_QA.py              │    │
│  │  (Streamlit · 知识库管理) │    │   (Streamlit · 用户问答)     │    │
│  │                          │    │                               │    │
│  │  管理员上传 TXT 文档 ────►│    │  用户输入问题 ────────────────►│    │
│  └───────────┬──────────────┘    └──────────────┬────────────────┘    │
│              │                                   │                     │
│              ▼                                   ▼                     │
│  ┌──────────────────────┐    ┌───────────────────────────────────┐    │
│  │  knowleage_base.py   │    │           rag.py                  │    │
│  │  KnowledgeBaseService│    │         RagService                │    │
│  │                      │    │                                   │    │
│  │  1. MD5 去重校验     │    │  1. 构建 LCEL 链:                 │    │
│  │  2. 递归文本分割     │    │     input → retrieve → prompt     │    │
│  │  3. 文本向量化       │    │     → ChatTongyi → output         │    │
│  │  4. 存入 ChromaDB    │    │  2. 包装消息历史 Runnable         │    │
│  └───────────┬──────────┘    └──────────────┬────────────────────┘    │
│              │                               │                         │
│              ▼                               ▼                         │
│  ┌──────────────────────┐    ┌───────────────────────────────────┐    │
│  │   vector_stores.py   │    │     file_history_store.py         │    │
│  │  Vector_StoreService │    │    FileChatMessageHistory         │    │
│  │                      │    │                                   │    │
│  │  ChromaDB 封装层     │    │  按 session_id 读写 JSON 会话文件  │    │
│  │  · get_retriever()   │    │                                   │    │
│  └───────────┬──────────┘    └──────────────┬────────────────────┘    │
│              │                               │                         │
│              ▼                               ▼                         │
│  ┌──────────────────────┐    ┌───────────────────────────────────┐    │
│  │     chroma_db/       │    │        chat_history/              │    │
│  │  (ChromaDB 持久化)   │    │   (会话历史 JSON 文件)            │    │
│  │  · chroma.sqlite3    │    │   · user_001                      │    │
│  │  · HNSW 索引文件     │    │                                   │    │
│  └──────────────────────┘    └───────────────────────────────────┘    │
│                                                                       │
│  ┌───────────────────────────────────────────────────────────────┐   │
│  │                     config_data.py                              │   │
│  │  所有可调参数集中管理: 分块大小、模型名称、路径、阈值等          │   │
│  └───────────────────────────────────────────────────────────────┘   │
└──────────────────────────────────────────────────────────────────────┘

技术栈

层级 技术 说明
LLM 阿里云 Tongyi Qwen3-Max 基于参考资料生成专业回复
Embedding 阿里云 DashScope text-embedding-v4 文本向量化
向量数据库 ChromaDB (HNSW 索引) 文档向量存储与语义检索
RAG 框架 LangChain (LCEL) 链式编排:检索 → 提示词 → 生成
前端 Streamlit 两个独立 Web 应用
会话持久化 文件系统 JSON 按 session_id 存储对话历史

目录结构

RAGProject/
│
├── config_data.py               # 全局配置中心(路径、模型、阈值等参数)
├── rag.py                       # RAG 核心服务:构建 LCEL 链,编排检索与生成
├── vector_stores.py             # ChromaDB 向量存储封装,提供 retriever
├── knowleage_base.py            # 知识库服务:文档摄取、分块、去重、入库
├── file_history_store.py        # 文件驱动的 LangChain 对话历史存储
│
├── app_QA.py                    # Streamlit 应用:用户智能问答界面
├── app_file_uploader.py         # Streamlit 应用:知识库文档上传界面
│
├── data/                        # 原始知识库文档
│   ├── 尺码推荐.txt              #   身高体重 → 尺码对照表
│   ├── 洗涤养护.txt              #   面料洗护保养指南(按季节/材质)
│   └── 颜色选择.txt              #   肤色/场合/体型颜色搭配建议
│
├── chroma_db/                   # ChromaDB 持久化向量存储(自动生成)
│   ├── chroma.sqlite3           #   向量元数据数据库
│   └── <uuid>/                  #   向量集合数据目录
│       ├── data_level0.bin      #     嵌入向量二进制数据
│       ├── header.bin           #     索引头信息
│       ├── length.bin           #     向量长度元数据
│       └── link_lists.bin       #     HNSW 图链接表
│
├── chat_history/                # 对话历史持久化(自动生成)
│   └── user_001                 #   session_id 对应的 JSON 消息文件
│
└── md5.txt                      # 已入库文档 MD5 记录(去重用)

数据流

1. 文档摄入流程(知识库更新)

用户上传 .txt 文件
    │
    ▼
app_file_uploader.py ─── 读取文件内容,解码为 UTF-8 字符串
    │
    ▼
KnowledgeBaseService.upload_by_str()
    │
    ├── [1] 计算文本 MD5 → 与 md5.txt 比对去重
    │       └── 已存在 → 返回 "[跳过]内容已经存在知识库里"
    │
    ├── [2] 文本长度 > max_split_char_number (1000)?
    │       ├── 是 → RecursiveCharacterTextSplitter 分割
    │       │        chunk_size=1000, chunk_overlap=100
    │       └── 否 → 保持原文不分割
    │
    ├── [3] 为每个 chunk 附加元数据
    │       {source, create_time, operator}
    │
    ├── [4] Chroma.add_texts() → DashScope Embedding → 写入 chroma_db/
    │
    └── [5] 记录 MD5 到 md5.txt → 返回成功信息

2. 问答检索与生成流程

用户输入问题
    │
    ▼
RagService chain.invoke() / chain.stream()
    │
    ├── [1] RunnablePassthrough ─── 保持原始 input 传递
    │
    ├── [2] 并行分支: format_for_retriever(input)
    │       │
    │       ├── Vector_StoreService.get_retriever()
    │       │       └── ChromaDB.similarity_search(query, k=2)
    │       │               └── 返回 Top-2 最相关文档片段
    │       │
    │       └── format_document(docs)
    │               └── 将文档片段拼接为上下文字符串
    │
    ├── [3] format_for_prompt_template()
    │       └── 组装 {input, context, history} 三要素
    │
    ├── [4] ChatPromptTemplate
    │       ├── System: "以我提供的已知参考资料为主,简洁和专业的回答..."
    │       │          context: {检索到的文档片段}
    │       ├── System: "并且我提供用户的对话历史记录如下:"
    │       ├── Placeholder: {history} ← 从 FileChatMessageHistory 加载
    │       └── Human: "请回答用户的提问:{input}"
    │
    ├── [5] print_prompt() ─── 控制台输出完整提示词(调试用)
    │
    ├── [6] ChatTongyi (qwen3-max) ─── 调用阿里云 DashScope 生成回复
    │
    └── [7] StrOutputParser ─── 提取纯文本输出
            │
            ├── stream() 模式 → 逐 token 推送至 Streamlit 前端
            └── FileChatMessageHistory.add_messages() → 持久化本轮对话

模块详解

config_data.py — 全局配置

所有可调参数集中管理,避免硬编码分散:

参数 默认值 说明
md5_path "./md5.txt" 已入库文档 MD5 记录文件路径
collection_name "rag" ChromaDB 集合名称
persist_directory "./chroma_db" ChromaDB 持久化目录
chunk_size 1000 文本分块最大字符数
chunk_overlap 100 相邻分块重叠字符数
separators [".","\\n\\n","\\n",".","。","?","?","!","!"," ",""] 递归分割优先级分隔符
max_split_char_number 1000 低于此长度的文本不分割
similarity_threshold 2 检索返回 Top-K 文档数
embedding_model_name "text-embedding-v4" DashScope 嵌入模型
chat_model_name "qwen3-max" Tongyi 对话模型
session_config {"session_id": "user_001"} 默认会话配置

vector_stores.py — 向量存储服务

封装 ChromaDB,对外提供统一的检索接口:

class Vector_StoreService:
    def __init__(self, embedding):
        # 使用 config 中的 collection_name 和 persist_directory
        # 创建 Chroma 向量存储实例

    def get_retriever(self):
        # 返回 LangChain Retriever,k = config.similarity_threshold

knowleage_base.py — 知识库服务

负责文档摄入的完整生命周期管理:

  • get_string_md5(input_str):计算字符串 MD5 摘要
  • check_md5(md5_str) / save_md5(md5_str):去重判断与记录
  • KnowledgeBaseService
    • upload_by_str(data, file_name):核心摄入方法,串联去重→分块→向量化→存储全流程

rag.py — RAG 核心服务

系统的核心编排模块,使用 LangChain LCEL 声明式构建处理链:

RunnableParallel({
    input:   RunnablePassthrough(),
    context: Retriever 链
})
  → Prompt 格式化
  → ChatPromptTemplate
  → ChatTongyi (qwen3-max)
  → StrOutputParser

通过 RunnableWithMessageHistory 包装,自动从 FileChatMessageHistory 加载/保存对话历史。

file_history_store.py — 对话历史存储

实现 LangChain 的 BaseChatMessageHistory 接口,将每个 session 的对话历史序列化为 JSON 文件:

class FileChatMessageHistory(BaseChatMessageHistory):
    # 文件路径: ./chat_history/{session_id}

    def add_messages(self, messages):
        # 追加消息并序列化为 JSON

    @property
    def messages(self):
        # 读取 JSON 并反序列化为 BaseMessage 列表

app_QA.py — 用户问答界面

基于 Streamlit 的聊天式 UI:

  • 初始化 RagService 并缓存于 st.session_state
  • 展示对话历史(含欢迎消息)
  • 用户输入后通过 chain.stream() 流式输出 AI 回复
  • 自动持久化每轮对话

app_file_uploader.py — 知识库管理界面

基于 Streamlit 的文档上传界面:

  • 支持上传 .txt 文件
  • 显示文件名、MIME 类型、文件大小
  • 调用 KnowledgeBaseService.upload_by_str() 完成入库
  • 展示处理结果(成功 / 已跳过)

快速开始

环境要求

  • Python ≥ 3.10
  • 阿里云 DashScope API Key(需开通 DashScope 服务)

1. 安装依赖

本项目作为 lc-course 的子模块,依赖由父级 pyproject.toml 通过 uv 管理:

# 在项目根目录 (lc-course/)
pip install uv  # 如未安装 uv
uv sync

或手动安装核心依赖:

pip install langchain langchain-chroma langchain-community langchain-text-splitters
pip install chromadb dashscope streamlit python-dotenv

2. 配置环境变量

在项目根目录 lc-course/ 下创建 .env 文件:

DASHSCOPE_API_KEY=your_dashscope_api_key_here

在阿里云 DashScope 控制台获取 API Key。

3. 上传知识文档

启动知识库管理应用:

streamlit run app_file_uploader.py

在浏览器中上传 data/ 目录下的 3 个知识文档(或自定义 .txt 文件):

  • 尺码推荐.txt
  • 洗涤养护.txt
  • 颜色选择.txt

4. 启动问答服务

streamlit run app_QA.py

在聊天框中输入问题(如 "我身高170cm,体重70kg,应该选什么尺码?"),系统将基于知识库返回专业回复。


配置说明

所有可调参数位于 config_data.py,可根据业务需求调整:

调优场景 建议修改
提高检索精度 降低 similarity_threshold(返回更少但更相关的文档)
扩大检索范围 提高 similarity_threshold(返回更多参考文档)
调整分块粒度 修改 chunk_sizechunk_overlap
切换模型 修改 embedding_model_name / chat_model_name 为其他 DashScope 支持的模型
多用户隔离 为不同用户设置不同的 session_config["session_id"]
添加自定义分隔符 separators 列表中添加适合业务文本的分隔符

使用方法

命令行调试

可以单独运行各模块进行调试:

# 测试向量检索
python vector_stores.py

# 测试知识库服务
python knowleage_base.py

# 测试 RAG 链(注意:需要先确保知识库有数据)
python rag.py

扩展知识领域

  1. 准备业务相关的 .txt 文档
  2. 通过 app_file_uploader.py 上传,或直接将文件放入 data/ 目录后调用 KnowledgeBaseService.upload_by_str()
  3. 系统自动完成分块、向量化和去重,无需重启问答服务

依赖清单

依赖 版本 用途
langchain ≥1.2.18 RAG 链编排框架
langchain-chroma ≥1.1.0 ChromaDB 向量存储集成
langchain-community ≥0.4.1 DashScope Embeddings、ChatTongyi 集成
langchain-text-splitters ≥1.1.2 RecursiveCharacterTextSplitter 文本分割
chromadb ≥1.5.9 向量数据库(HNSW 索引)
dashscope ≥1.25.18 阿里云 DashScope SDK(嵌入 + 对话模型)
streamlit ≥1.57.0 Web UI 框架
python-dotenv ≥1.2.2 环境变量管理

架构说明

  • 两应用分离app_file_uploader.py(管理端)和 app_QA.py(用户端)是两个独立的 Streamlit 应用,可分别部署和授权。
  • 配置统一:所有参数集中在 config_data.py,各模块通过 import 引用,避免配置分散。
  • 去重机制:知识库摄入时通过 MD5 摘要去重,防止同一文档重复入库。
  • LLM 接地:系统提示词明确要求"以我提供的已知参考资料为主",确保回复不会偏离知识库内容。
  • 流式交互:使用 LangChain 的 .stream() 方法 + Streamlit 的 write_stream() 实现打字机效果的实时输出。

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages