Skip to content

Qihang7/assistant

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

projectAgent — 智能扫地机器人客服助手

基于 LangChain + LangGraph 构建的 ReAct(Reasoning + Acting)智能体,以阿里通义千问(Qwen)大模型为核心,结合 RAG(检索增强生成) 技术,为"智扫通"品牌扫地机器人 / 扫拖一体机提供智能客服问答、个性化使用报告生成等服务。

前端使用 Streamlit 构建 Web 聊天界面,支持流式输出。


功能特性

  • 知识库问答 — 基于 RAG 技术,从产品手册、故障排除、维护保养、选购指南等知识文档中检索相关内容并生成精准回答
  • 个性化使用报告 — 根据用户操作记录(模拟后端数据),自动生成月度使用情况报告与保养建议(Markdown 格式)
  • 动态角色切换 — 通过中间件机制,智能体可在"客服助手"和"报告撰写师"两种角色间自动切换
  • 环境感知 — 可查询天气信息(模拟),结合用户所在地给出环境相关建议
  • 流式输出 — 前端支持打字机效果的流式响应,提升用户体验
  • 文档自动去重 — 知识库文件通过 MD5 校验避免重复入库

项目架构

┌──────────────────────────────────────────────┐
│              Streamlit UI (app.py)           │
│          Web 聊天界面 · 流式输出              │
└──────────────────┬───────────────────────────┘
                   │
                   ▼
┌──────────────────────────────────────────────┐
│           ReactAgent (agent/react_agent.py)  │
│   ┌─────────────────────────────────────┐   │
│   │  LangChain create_agent()           │   │
│   │  ┌───────────────────────────────┐  │   │
│   │  │ System Prompt (动态切换)      │  │   │
│   │  ├───────────────────────────────┤  │   │
│   │  │ 7 个 Tool 工具               │  │   │
│   │  │ rag_summarize · get_weather  │  │   │
│   │  │ get_user_id · get_user_loc   │  │   │
│   │  │ get_current_month             │  │   │
│   │  │ fetch_external_data           │  │   │
│   │  │ fill_context_for_report       │  │   │
│   │  ├───────────────────────────────┤  │   │
│   │  │ 3 个 Middleware 中间件        │  │   │
│   │  │ monitor_tool · log_before_    │  │   │
│   │  │ model · report_prompt_switch  │  │   │
│   │  └───────────────────────────────┘  │   │
│   └─────────────────────────────────────┘   │
└──────┬──────────────┬───────────────────────┘
       │              │
       ▼              ▼
┌──────────────┐ ┌─────────────────────────────┐
│ RAG Service  │ │    Model Factory             │
│ (rag/)       │ │    (model/factory.py)        │
│ ┌──────────┐ │ │ ┌─────────────────────────┐ │
│ │ ChromaDB │ │ │ │ ChatTongyi (qwen3-max)  │ │
│ │ 向量存储  │ │ │ ├─────────────────────────┤ │
│ ├──────────┤ │ │ │ DashScopeEmbeddings     │ │
│ │ 文档切分  │ │ │ │ (text-embedding-v4)    │ │
│ ├──────────┤ │ │ └─────────────────────────┘ │
│ │ 检索链   │ │ └─────────────────────────────┘
│ └──────────┘ │
└──────────────┘

项目目录结构

projectAgent/
├── README.md                         # 项目技术文档(本文件)
├── .python-version                   # Python 版本声明 (3.13)
├── .env                              # 环境变量(API Key 等)
├── .gitignore                        # Git 忽略配置
├── pyproject.toml                    # 项目元数据与依赖声明
├── uv.lock                           # 依赖锁定文件
├── md5.txt                           # 已入库文档的 MD5 校验值(去重用)
│
├── app.py                            # 【入口】Streamlit Web 前端
├── main.py                           # 占位文件,打印 Hello from projectagent!
│
├── agent/                            # ── 智能体层 ──
│   ├── react_agent.py                #   ReAct 智能体核心:创建 agent、流式执行
│   ├── chroma_db/                    #   测试用 ChromaDB 实例(空)
│   └── tools/
│       ├── agent_tools.py            #   7 个 @tool 工具函数 + CSV 数据加载
│       ├── middleware.py             #   3 个 LangChain 中间件
│       └── chroma_db/                #   测试用 ChromaDB 实例(空)
│
├── config/                           # ── 配置层(YAML)──
│   ├── agent.yml                     #   外部数据路径配置(records.csv)
│   ├── chroma.yml                    #   ChromaDB 设置:集合名、分块参数、文件类型
│   ├── prompts.yml                   #   提示词文件路径配置
│   └── rag.yml                       #   RAG 模型名称配置
│
├── data/                             # ── 数据层 ──
│   ├── external/
│   │   └── records.csv               #   用户使用记录(10 用户 × 12 月,共 120 行)
│   ├── 扫地机器人100问.pdf            #   知识库:扫地机器人百问百答 (PDF)
│   ├── 扫地机器人100问2.txt           #   知识库:扫地机器人百问百答 变体 2
│   ├── 扫拖一体机器人100问.txt        #   知识库:扫拖一体机器人百问百答
│   ├── 故障排除.txt                   #   知识库:故障排查指南
│   ├── 维护保养.txt                   #   知识库:维护保养指南
│   └── 选购指南.txt                   #   知识库:选购指南
│
├── logs/                             # ── 日志目录 ──
│   └── agent_YYYY-MM-DD_HH-MM-SS.log #   带时间戳的运行日志
│
├── model/                            # ── 模型工厂 ──
│   └── factory.py                    #   抽象工厂模式:ChatModel + Embeddings 工厂
│
├── prompts/                          # ── 提示词模板 ──
│   ├── main_prompt.txt               #   系统提示词:客服助手模式
│   ├── rag_prompt.txt                #   RAG 检索链提示词模板(含 {input}、{context})
│   └── report_prompt.txt             #   系统提示词:报告撰写模式
│
├── rag/                              # ── RAG 检索增强生成层 ──
│   ├── rag_service.py                #   RAG 总结服务:检索 + 提示词 + 模型 + 解析器
│   ├── vector_store.py               #   Chroma 向量存储管理:文档加载、切分、MD5 去重
│   └── chroma_db/                    #   【主】ChromaDB 持久化向量数据库
│       ├── chroma.sqlite3            #     向量元数据
│       └── 35bcfc11-.../             #     向量索引二进制文件
│
└── utils/                            # ── 工具层 ──
    ├── config_handler.py             #   YAML 配置文件加载器
    ├── file_handler.py               #   文件处理:MD5 哈希、类型过滤、PDF/TXT 加载器
    ├── logger_handler.py             #   日志配置:控制台 + 文件双输出
    ├── path_tool.py                  #   项目根路径解析
    └── prompt_loader.py              #   提示词文件读取器

各文件详细说明

🟢 入口文件

app.py — Streamlit Web 前端

项目的启动入口。负责:

  • 初始化 ReactAgent 实例并缓存在 st.session_state 中(单例模式)
  • 渲染聊天界面(用户消息 + 助手回复)
  • 调用 execute_stream() 获取流式响应,逐字输出实现打字机效果
  • 管理对话历史记录

main.py — 占位文件

仅输出 Hello from projectagent!,未参与实际应用逻辑。可能是项目初始化时的测试文件。


🟡 智能体层 (agent/)

agent/react_agent.py — ReAct 智能体核心

项目的核心逻辑模块。使用 LangChain 的 create_agent() 组装智能体:

  • 模型:通过 model/factory.py 获取 ChatTongyi(qwen3-max) 实例
  • 系统提示词:从 prompts/main_prompt.txt 加载
  • 工具集:注册 7 个 @tool 函数,覆盖 RAG 检索、天气查询、用户数据获取等
  • 中间件:注册 3 个中间件实现工具调用监控、日志记录和动态提示词切换
  • 运行时上下文:维护 {"report": False} 上下文,用于控制角色切换
  • 流式执行execute_stream() 通过 agent.stream(stream_mode="values") 实现流式输出

agent/tools/agent_tools.py — 工具函数集

定义智能体可调用的 7 个工具:

工具函数 类型 功能描述
rag_summarize(query) 核心 调用 RAG 服务检索知识库并生成回答
get_weather(city, date) 模拟 返回模拟的天气数据(温度、湿度、天气状况)
get_user_id() 模拟 返回模拟用户 ID(当前返回 "user_1001"
get_user_location() 模拟 返回模拟用户所在城市(当前返回 "北京市"
get_current_month() 模拟 返回当前月份("2025-01"
fetch_external_data(user_id, month) 核心 records.csv 查询用户指定月份的使用数据
fill_context_for_report() 信号 空操作工具,作为触发报告模式的信号

还包含 generate_external_data() 函数,惰性加载并解析 records.csv 为嵌套字典结构:

{user_id: {month: {Feature, CleaningEfficiency, Consumables, Comparison, Time}}}

agent/tools/middleware.py — 中间件

三个 LangChain 中间件,以装饰器形式注册:

中间件 装饰器 作用
monitor_tool @wrap_tool_call 包装每个工具调用:记录输入/输出日志;检测到 fill_context_for_report 被调用时将 context["report"] 设为 True
log_before_model @before_model 每次 LLM 调用前记录当前消息数量
report_prompt_switch @dynamic_prompt 动态提示词切换器:当 context["report"] == True 时,将系统提示词替换为 report_prompt.txt

🔵 模型工厂 (model/)

model/factory.py — 抽象工厂

使用抽象工厂模式创建模型实例:

  • BaseModelFactory:抽象基类,定义 create() 接口
  • ChatModelFactory:创建 ChatTongyi(model="qwen3-max") 实例
  • EmbeddingsFactory:创建 DashScopeEmbeddings(model="text-embedding-v4") 实例
  • 模块级单例 chat_modelembed_model,在导入时即创建,全局复用

🟣 RAG 检索增强生成层 (rag/)

rag/rag_service.py — RAG 总结服务

构建并管理 RAG 检索链:

  • 初始化 VectorStoreService 获取向量存储实例
  • 将向量存储包装为 LangChain Retriever(top-k 检索)
  • 构建 LCEL 链:PromptTemplate ← chat_model ← StrOutputParser
  • rag_summarize(query) 方法:检索 → 格式化上下文 → 调用 LLM → 返回结构化回答

rag/vector_store.py — 向量存储管理

管理 ChromaDB 向量数据库的完整生命周期:

  • 初始化:连接 Chroma(持久化模式),创建 RecursiveCharacterTextSplitter(200 字符块、20 字符重叠、中文友好分隔符)
  • 文档加载 (load_document()):
    1. 扫描 data/ 目录下的 .txt.pdf 文件
    2. 计算文件 MD5,与 md5.txt 比对,跳过已入库文件
    3. 使用 PyPDFLoader / TextLoader 加载新文件
    4. 切分为文本块,通过 DashScopeEmbeddings 向量化
    5. 存入 ChromaDB,更新 md5.txt
  • 检索 (get_retriever()):返回配置了 top-k 的检索器

🟠 配置层 (config/)

文件 关键配置项 说明
rag.yml chat_model_name: qwen3-max
embedding_model_name: text-embedding-v4
LLM 和嵌入模型名称
chroma.yml collection_name: agent
persist_directory: chroma_db
k: 3
chunk_size: 200
chunk_overlap: 20
allowed_types: [txt, pdf]
md5_hex_store: md5.txt
data_path: data
中文分隔符列表
向量数据库及文档处理配置
prompts.yml main_prompt_path
rag_summarize_prompt_path
report_prompt_path
三个提示词文件的相对路径
agent.yml external_data_path: data/external/records.csv 外部用户数据 CSV 路径
.env DASHSCOPE_API_KEY
DASHSCOPE_BASE_URL
阿里云 DashScope API 密钥和端点

🟤 提示词模板 (prompts/)

prompts/main_prompt.txt — 客服助手模式提示词

定义智能体为"智扫通产品专家",遵循 ReAct 循环。详细描述:

  • 7 个工具的用途、适用场景和调用规则
  • 严格的 5 次工具调用上限(超限后必须给出最终回答或承认能力不足)
  • 报告生成的固定流程:get_user_id → get_current_month → fill_context_for_report → fetch_external_data
  • 回答规范:中文回答、结构化输出、禁止虚构信息

prompts/rag_prompt.txt — RAG 检索链提示词

包含 {input}{context} 占位符。要求模型:

  • 严格依据参考资料回答
  • 仅使用中文
  • 不添加额外结构或推测

prompts/report_prompt.txt — 报告撰写模式提示词

角色切换后的系统提示词,将智能体重新定位为"专业报告撰写师"。特点:

  • 仅列出 4 个报告相关工具(get_user_idget_current_monthfetch_external_datarag_summarize
  • 要求输出 Markdown 格式,标题为"智扫通扫地机器人使用情况报告与保养建议"

🟢 工具层 (utils/)

文件 功能
config_handler.py 加载 4 个 YAML 配置文件为模块级字典:rag_confchroma_confprompts_confagent_conf
file_handler.py get_file_md5_hex() — 流式 MD5 哈希;listdir_with_allowed_type() — 按扩展名过滤文件;pdf_load() / txt_load() — 文档加载器
logger_handler.py 创建名为 "agent" 的 Logger,同时输出到控制台 (INFO) 和带时间戳的文件 (DEBUG)
path_tool.py get_project_root() — 根据当前文件位置推导项目根目录;get_abs_path() — 将相对路径转为绝对路径
prompt_loader.py load_system_prompts() / load_rag_prompts() / load_report_prompts() — 从 prompts.yml 配置的路径读取对应的 .txt 提示词文件

核心技术栈

技术 版本 用途
Python 3.13+ 编程语言
LangChain >=1.3.2 智能体框架(ReAct Agent、Tools、Middleware、Chains)
LangGraph (依赖) 运行时上下文与指令类型支持
Streamlit >=1.58.0 Web 聊天界面
ChromaDB >=1.5.9 向量数据库,RAG 知识存储与检索
DashScope >=1.25.19 阿里云灵积模型服务 SDK(通义千问 LLM + 文本嵌入)
langchain-chroma >=1.1.0 LangChain 与 ChromaDB 的集成
langchain-community >=0.4.2 社区集成(ChatTongyi、文档加载器等)
pypdf >=6.12.2 PDF 文档解析
PyYAML >=6.0.3 YAML 配置文件解析
python-dotenv (间接) .env 环境变量加载
uv Python 包管理器

快速开始

前置条件

  • Python 3.13+
  • uv 包管理器
  • 阿里云 DashScope API Key(获取地址

安装与运行

# 1. 克隆项目
git clone <repo-url>
cd projectAgent

# 2. 配置环境变量
# 编辑 .env 文件,填入你的 API Key
# DASHSCOPE_API_KEY=your-api-key
# DASHSCOPE_BASE_URL=https://dashscope.aliyuncs.com/api/v1

# 3. 安装依赖
uv sync

# 4. 初始化知识库(首次运行或知识库文件有更新时执行)
uv run python -m rag.vector_store

# 5. 启动 Web 应用
uv run streamlit run app.py

启动后,浏览器访问 http://localhost:8501 即可使用。


工作流程

普通问答流程

用户提问
  → ReAct Agent 接收问题(main_prompt.txt 模式)
  → Agent 推理:是否需要工具?
    ├── 需要 → 调用工具(如 rag_summarize)
    │         → RAG Service 检索 ChromaDB
    │         → LLM 基于检索结果生成回答
    │         → 返回工具结果给 Agent
    │         → Agent 继续推理...
    └── 不需要 → 直接生成最终回答
  → 流式输出到前端

报告生成流程

用户请求报告(如"生成我的使用报告")
  → Agent 识别为报告请求
  → 执行固定流程:
     1. get_user_id() → 获取用户 ID
     2. get_current_month() → 获取当前月份
     3. fill_context_for_report() → 触发 report_prompt_switch 中间件
  → 系统提示词自动切换为 report_prompt.txt
  → 4. fetch_external_data(user_id, month) → 查询用户使用数据
  → 5. rag_summarize(query) → 检索相关保养知识
  → Agent 整合数据,生成 Markdown 格式报告
  → 流式输出到前端

知识库入库流程

执行 python -m rag.vector_store
  → 扫描 data/ 目录所有 .txt / .pdf 文件
  → 对每个文件计算 MD5
  → 与 md5.txt 比对
    ├── 已存在 → 跳过
    └── 新文件 → 加载文档 → 文本切分 → 向量化嵌入 → 存入 ChromaDB
  → 更新 md5.txt

设计模式

模式 应用位置 说明
ReAct Agent agent/react_agent.py 推理-行动循环,智能体自主决定调用工具获取信息
抽象工厂 model/factory.py ChatModelFactory / EmbeddingsFactory 统一创建模型实例
中间件链 agent/tools/middleware.py 工具调用拦截、日志记录、动态提示词切换
RAG rag/ 检索增强生成:文档检索 → 上下文注入 → 精准回答
单例模式 app.py / model/factory.py ReactAgent 通过 st.session_state 单例化;模型实例为模块级单例
配置-代码分离 config/ + prompts/ 所有配置和提示词独立于代码,便于维护和调整

注意事项

  1. 模拟数据get_weatherget_user_idget_user_locationget_current_month 目前返回的是硬编码的模拟数据,生产部署时需替换为真实 API 调用
  2. API Key:确保 .env 中的 DASHSCOPE_API_KEY 有效且有足够配额
  3. 知识库更新:添加新知识文档到 data/ 目录后,需重新运行 python -m rag.vector_store 以入库
  4. Python 版本:项目要求 Python 3.13+,建议使用 uv 管理环境
  5. ChromaDB 目录rag/chroma_db/ 是主向量数据库,agent/chroma_db/agent/tools/chroma_db/ 为测试残留,可忽略

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages