From aadfb1ec9edf412a2f00bd669eb614d9da13b9e0 Mon Sep 17 00:00:00 2001 From: HengZhang Date: Mon, 2 Mar 2026 14:31:13 +0800 Subject: [PATCH] =?UTF-8?q?=E7=A7=BB=E9=99=A4=E5=86=97=E4=BD=99=E6=96=87?= =?UTF-8?q?=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 30 ++- README.md | 274 ++++++++++++++++++++++++ app.py | 46 ++++ docs/IMPORTS_SUMMARY.md | 358 +++++++++++++++++++++++++++++++ docs/INTERVIEW_PREP.md | 387 ++++++++++++++++++++++++++++++++++ docs/LANGCHAIN_PACKAGE_MAP.md | 200 ++++++++++++++++++ docs/PROJECT_OUTLINE.md | 276 ++++++++++++++++++++++++ lesson/01_Agent.py | 26 +++ lesson/02_Stream.py | 37 ++++ lesson/03_ReAct.py | 39 ++++ lesson/04_middle_ware.py | 70 ++++++ logs/Agent_20260301.log | 164 ++++++++++++++ requirements.txt | 36 ++++ 13 files changed, 1940 insertions(+), 3 deletions(-) create mode 100644 README.md create mode 100644 docs/IMPORTS_SUMMARY.md create mode 100644 docs/INTERVIEW_PREP.md create mode 100644 docs/LANGCHAIN_PACKAGE_MAP.md create mode 100644 docs/PROJECT_OUTLINE.md create mode 100644 lesson/01_Agent.py create mode 100644 lesson/02_Stream.py create mode 100644 lesson/03_ReAct.py create mode 100644 lesson/04_middle_ware.py create mode 100644 requirements.txt diff --git a/.gitignore b/.gitignore index a80ea30..205dab5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,28 @@ +# 版本控制目录 .git -.idea -.__pycache__/ -.chroma_db/ \ No newline at end of file + +# IDE 配置 +.idea/ + +# Python 编译文件 +__pycache__/ + +# 向量数据库 +chroma_db/ + +# 日志文件 +logs/ + +# 临时文件 +*.tmp +*.temp + +# 环境文件 +.env + +# 依赖目录 +venv/ +env/ + +# MD5 记录文件 +md5.txt \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..7cf5dff --- /dev/null +++ b/README.md @@ -0,0 +1,274 @@ +# 智扫通智能机器人客服 + +> 基于 LangChain + RAG + Agent 的智能问答系统,专注于扫地机器人和扫拖一体机器人的专业客服 + +## 项目简介 + +智扫通是一个基于大语言模型的智能客服系统,利用 LangChain 的 Agent 框架和 RAG (检索增强生成) 技术,为用户提供专业、准确的扫地机器人相关问答服务。 + +### 核心功能 +- **智能问答**:基于 ReAct 框架的 Agent 自主工具调用 +- **专业知识库**:通过 RAG 从向量库检索专业资料 +- **个性化服务**:支持生成用户使用报告 +- **多轮对话**:保持会话上下文,提供连贯回答 +- **流式输出**:实时显示思考过程和回答内容 + +## 技术栈 + +| 类别 | 技术/框架 | 版本 | +|------|----------|------| +| 前端 | Streamlit | 最新 | +| AI 框架 | LangChain | >= 0.3.0 | +| 大语言模型 | 通义千问 (qwen3-max) | - | +| 向量数据库 | Chroma | 最新 | +| Embedding | DashScope (text-embedding-v4) | - | +| 配置管理 | YAML | - | +| 语言 | Python | 3.9+ | + +## 安装指南 + +### 1. 环境要求 +- Python 3.9 或更高版本 +- 已配置阿里云 DashScope API 密钥 + +### 2. 安装依赖 + +```bash +# 克隆项目 +git clone https://github.zhang-heng.com/czzhangheng/agent_proj +cd agent_proj + +# 安装依赖 +pip install -r requirements.txt +``` + +### 3. 配置环境变量 + +在项目根目录创建 `.env` 文件,添加以下内容: + +```bash +# DashScope API 密钥 +DASHSCOPE_API_KEY=your_api_key_here +``` + +### 4. 知识库初始化 + +首次运行前需要初始化知识库: + +```bash +# 加载知识库到向量库 +python -m rag.vector_store +``` + +## 快速开始 + +### 1. 启动 Web 应用 + +```bash +# 启动 Streamlit 应用 +streamlit run app.py +``` + +### 2. 访问界面 + +打开浏览器访问:`http://localhost:8501` + +### 3. 开始对话 + +在聊天输入框中输入问题,例如: +- "扫地机器人如何保养?" +- "推荐适合小户型的扫地机器人" +- "生成我的使用报告" + +## 项目结构 + +``` +agent_proj/ +├── agent/ # Agent 核心模块 +│ ├── tools/ # 工具定义和中间件 +│ └── react_agent.py # ReAct Agent 封装 +│ +├── config/ # 配置文件 +│ ├── agent.yaml # Agent 配置 +│ ├── chroma.yaml # 向量库配置 +│ ├── prompts.yaml # Prompt 路径配置 +│ └── rag.yaml # RAG 模型配置 +│ +├── data/ # 知识库和外部数据 +│ ├── external/ # 外部数据 (CSV) +│ └── 知识库文件 (pdf/txt) # 专业资料 +│ +├── docs/ # 项目文档 +│ +├── model/ # 模型工厂 +│ └── factory.py # LLM/Embedding 模型创建 +│ +├── prompts/ # Prompt 模板 +│ ├── main_prompt.txt # 主系统 Prompt +│ ├── rag_summarize.txt # RAG 总结 Prompt +│ └── report_prompt.txt # 报告生成 Prompt +│ +├── rag/ # RAG 服务 +│ ├── rag_service.py # RAG 总结服务 +│ └── vector_store.py # 向量存储服务 +│ +├── utils/ # 工具模块 +│ ├── config_handler.py # 配置加载 +│ ├── file_handler.py # 文件处理 +│ ├── logger_handler.py # 日志管理 +│ ├── path_tool.py # 路径工具 +│ └── prompt_loader.py # Prompt 加载 +│ +├── chroma_db/ # Chroma 向量数据库 +├── logs/ # 日志目录 +├── app.py # Streamlit 主应用 +├── requirements.txt # 依赖列表 +└── README.md # 项目说明 +``` + +## 核心模块 + +### Agent 模块 +- **ReactAgent**:封装 LangChain Agent,实现 ReAct 思考框架 +- **工具系统**:支持 7 种工具,包括 RAG 检索、天气查询、用户信息获取等 +- **中间件**:监控工具调用、动态提示词切换、日志记录 + +### RAG 模块 +- **向量存储**:基于 Chroma 实现知识向量存储 +- **文档加载**:支持 PDF 和 TXT 文件 +- **文本分片**:使用 RecursiveCharacterTextSplitter 进行智能分片 +- **相似度检索**:基于余弦相似度的 Top-K 检索 + +### 模型管理 +- **模型工厂**:统一管理 LLM 和 Embedding 模型 +- **动态配置**:通过 YAML 配置文件管理模型参数 + +## 配置说明 + +### 1. RAG 配置 (`config/rag.yaml`) + +```yaml +# 大语言模型 +chat_model_name: "qwen3-max" + +# Embedding 模型 +embeddings_model_name: "text-embedding-v4" +``` + +### 2. 向量库配置 (`config/chroma.yaml`) + +```yaml +# 集合名称 +collection_name: "agent" + +# 持久化目录 +persist_directory: "chroma_db" + +# 检索 Top-K +k: 3 + +# 数据目录 +data_path: "data" + +# 分片配置 +chunk_size: 200 +chunk_overlap: 20 +separators: ["\n\n", "\n", ".", "!", "?", "。", "?", "!", " "] +``` + +### 3. Agent 配置 (`config/agent.yaml`) + +```yaml +# 外部数据路径 +external_data_path: "data/external/records.csv" +``` + +### 4. Prompt 配置 (`config/prompts.yaml`) + +```yaml +# 主 Prompt 路径 +main_prompt_path: "prompts/main_prompt.txt" + +# RAG 总结 Prompt 路径 +rag_summarize_prompt_path: "prompts/rag_summarize.txt" + +# 报告 Prompt 路径 +report_prompt_path: "prompts/report_prompt.txt" +``` + +## 使用示例 + +### 1. 基本问答 + +**用户**:"扫地机器人如何处理毛发?" + +**系统**: +``` +我需要从知识库中检索关于扫地机器人处理毛发的专业信息,以便给出准确的回答。 + +[参考资料]: 扫地机器人在处理毛发时,应定期清理滚刷和边刷,建议每使用2-3次清理一次。对于宠物家庭,建议每天清理。部分高端机型配备防缠绕设计,可有效减少毛发缠绕问题。 | 参考源: {'source': 'data/维护保养.txt'} + +扫地机器人处理毛发的建议: +1. 定期清理滚刷和边刷,每使用2-3次清理一次 +2. 宠物家庭建议每天清理 +3. 选择配备防缠绕设计的高端机型 +4. 定期检查过滤网,避免毛发堵塞 +``` + +### 2. 个性化报告 + +**用户**:"生成我的使用报告" + +**系统**: +``` +我需要为用户生成使用报告,首先获取用户ID,然后获取当前月份,再调用报告上下文工具,最后获取用户的使用数据。 + +[工具调用] get_user_id +用户ID:1005 + +[工具调用] get_current_month +当前月份:2025-06 + +[工具调用] fill_context_for_report +fill_context_for_report已调用 + +[工具调用] fetch_external_data +用户1005在2025-06的使用数据:{'特征': '高效模式使用频繁', '效率': '平均清洁时间30分钟', '耗材': '滚刷损耗正常', '对比': '比上月提升15%'} + +根据您的使用数据,以下是您的6月使用报告: + +**使用特征**:高效模式使用频繁 +**清洁效率**:平均清洁时间30分钟 +**耗材状态**:滚刷损耗正常 +**性能对比**:比上月提升15% + +建议:继续保持良好的使用习惯,可考虑定期深度清洁机器内部。 +``` + +## 常见问题 + +### Q1: 如何添加新的知识库文件? + +1. 将 PDF 或 TXT 文件放入 `data/` 目录 +2. 重新运行知识库初始化命令: + ```bash + python -m rag.vector_store + ``` + +### Q2: 如何修改 Agent 的工具? + +编辑 `agent/tools/agent_tools.py` 文件,添加或修改工具定义。 + +### Q3: 如何调整 RAG 检索效果? + +修改 `config/chroma.yaml` 中的配置: +- `chunk_size`:调整文本分片大小 +- `k`:调整检索的文档数量 +- `separators`:调整文本分割策略 + +### Q4: 如何查看系统日志? + +日志文件位于 `logs/` 目录,按日期命名。 + + + diff --git a/app.py b/app.py index e69de29..4927bcb 100644 --- a/app.py +++ b/app.py @@ -0,0 +1,46 @@ +import time + +import streamlit as st +from agent.react_agent import ReactAgent + +st.title("智扫通智能机器人客服") +st.divider() + +if "agent" not in st.session_state: + st.session_state["agent"] = ReactAgent() + +if "message" not in st.session_state: + st.session_state["message"] = [] + +history = st.session_state["message"] +agent = st.session_state["agent"] + +for message in history: + st.chat_message(message["role"]).write(message["content"]) + +# 要求用胡输入提示词 +prompt = st.chat_input() + +if prompt: + st.chat_message("user").write(prompt) + history.append({"role": "user", "content": prompt}) + + response_messages = [] + with st.spinner("思考中"): + stream = agent.excute_stream(prompt) + + def capture(generator, cache_list): + for chunk in generator: + cache_list.append(chunk) + for char in chunk: + time.sleep(0.05) + yield char + + + st.chat_message("assistant").write_stream( + capture(stream, response_messages) + ) + history.append({"role": "assistant", "content": response_messages[-1]}) + st.rerun() + + diff --git a/docs/IMPORTS_SUMMARY.md b/docs/IMPORTS_SUMMARY.md new file mode 100644 index 0000000..c795581 --- /dev/null +++ b/docs/IMPORTS_SUMMARY.md @@ -0,0 +1,358 @@ +# 项目 Import 包汇总 + +> 本项目所有 Python 文件中使用的 import 包整理 + +--- + +## 一、第三方包 (pip install) + +### 1. LangChain 生态 + +| 包名 | 用途 | 来源 | +|------|------|------| +| `langchain` | Agent 核心框架 | `pip install langchain` | +| `langchain-core` | 核心抽象类 | `pip install langchain-core` | +| `langchain-community` | 第三方集成 (通义千问/DashScope) | `pip install langchain-community` | +| `langchain-chroma` | Chroma 向量数据库 | `pip install langchain-chroma` | +| `langchain-text-splitters` | 文本分片 | `pip install langchain-text-splitters` | +| `langgraph` | 图执行引擎 (中间件) | `pip install langgraph` | + +### 1.1 LangChain 具体导入 + +```python +# Agent +from langchain.agents import create_agent, AgentState +from langchain.agents.middleware import wrap_tool_call, before_model, dynamic_prompt, ModelRequest + +# Tools +from langchain_core.tools import tool +from langchain.tools.tool_node import ToolCallRequest + +# Messages +from langchain_core.messages import ToolMessage + +# Graph +from langgraph.types import Command +from langgraph.runtime import Runtime + +# Prompts +from langchain_core.prompts import PromptTemplate + +# Output Parsers +from langchain_core.output_parsers import StrOutputParser + +# Embeddings +from langchain_core.embeddings import Embeddings +``` + +### 1.2 社区包导入 + +```python +# LLM - 通义千问 +from langchain_community.chat_models.tongyi import ChatTongyi, BaseChatModel + +# Embedding - DashScope +from langchain_community.embeddings import DashScopeEmbeddings + +# Document Loaders +from langchain_community.document_loaders import PyPDFLoader, TextLoader + +# Document +from langchain_community.docstore.document import Document +``` + +### 1.3 Chroma & Text Splitters + +```python +# Vector Store +from langchain_chroma import Chroma + +# Text Splitter +from langchain_text_splitters import RecursiveCharacterTextSplitter +``` + +--- + +### 2. Web 框架 + +| 包名 | 用途 | +|------|------| +| `streamlit` | Web UI 界面 | + +```python +import streamlit as st +``` + +--- + +### 3. 配置管理 + +| 包名 | 用途 | +|------|------| +| `yaml` | YAML 配置文件解析 | + +```python +import yaml +``` + +--- + +### 4. 数据处理 + +| 包名 | 用途 | +|------|------| +| `pandas` | 数据处理 (CSV) | + +```python +import pandas +``` + +--- + +### 5. 其他工具 + +| 包名 | 用途 | +|------|------| +| `hashlib` | MD5 计算 (标准库) | +| `os` | 文件路径操作 (标准库) | +| `logging` | 日志管理 (标准库) | +| `time` | 时间控制 (标准库) | +| `typing` | 类型提示 (标准库) | +| `abc` | 抽象类 (标准库) | +| `datetime` | 日期时间 (标准库) | +| `random` | 随机数 (标准库) | + +--- + +## 二、标准库导入 + +```python +# 文件与路径 +import os +import os.path + +# 哈希计算 +import hashlib + +# 日志 +import logging + +# 时间 +import time + +# 日期 +from datetime import datetime + +# 随机数 +import random + +# 类型提示 +from typing import Optional, List, Callable + +# 抽象基类 +from abc import ABC, abstractmethod +``` + +--- + +## 三、按文件分类的导入 + +### app.py + +```python +import time +import streamlit as st +from agent.react_agent import ReactAgent +``` + +### 01_Agent.py / 02_Stream.py / 03_ReAct.py + +```python +from langchain.agents import create_agent +from langchain_community.chat_models.tongyi import ChatTongyi +from langchain_core.tools import tool +``` + +### agent/react_agent.py + +```python +from langchain.agents import create_agent +from model.factory import chat_model +from utils.prompt_loader import load_system_prompts +from agent.tools.agent_tools import (...) +from agent.tools.middleware import (...) +``` + +### agent/tools/agent_tools.py + +```python +import pandas +from langchain_core.tools import tool +from rag.rag_service import RagSummarizeService +import random +from utils.config_handler import agent_conf +from utils.path_tool import get_abs_path +from utils.logger_handler import logger +import os +``` + +### agent/tools/middleware.py + +```python +from langchain.agents.middleware import wrap_tool_call, before_model, dynamic_prompt, ModelRequest +from langchain.tools.tool_node import ToolCallRequest +from typing import Callable +from langchain_core.messages import ToolMessage +from langgraph.types import Command +from utils.logger_handler import logger +from langchain.agents import AgentState +from langgraph.runtime import Runtime +from utils.prompt_loader import load_system_prompts, load_report_prompts +``` + +### rag/rag_service.py + +```python +from langchain_core.output_parsers import StrOutputParser +from rag.vector_store import VectorStoreSerivce +from utils.prompt_loader import load_rag_prompts +from langchain_core.prompts import PromptTemplate +from model.factory import chat_model +from langchain_community.docstore.document import Document +from typing import List +from utils.logger_handler import logger +``` + +### rag/vector_store.py + +```python +import os.path +from langchain_chroma import Chroma +from utils.config_handler import chroma_conf +from model.factory import embedding_model +from langchain_text_splitters import RecursiveCharacterTextSplitter +import os +from utils.path_tool import get_abs_path +from utils.file_handler import pdf_loader, txt_loader, listdir_with_allowed_type, get_file_md5_hex +from utils.logger_handler import logger +from langchain_community.docstore.document import Document as Documents +``` + +### model/factory.py + +```python +from abc import ABC, abstractmethod +from typing import Optional +from utils.config_handler import rag_conf +from langchain_core.embeddings import Embeddings +from langchain_community.chat_models.tongyi import BaseChatModel +from langchain_community.chat_models.tongyi import ChatTongyi +from langchain_community.embeddings import DashScopeEmbeddings +``` + +### utils/config_handler.py + +```python +import yaml +from utils.path_tool import get_abs_path +``` + +### utils/logger_handler.py + +```python +import logging +import os +from utils.path_tool import get_abs_path +from datetime import datetime +``` + +### utils/prompt_loader.py + +```python +from utils.config_handler import prompts_conf +from utils.path_tool import get_abs_path +from utils.logger_handler import logger +``` + +### utils/file_handler.py + +```python +import hashlib +import os +from utils.logger_handler import logger +from langchain_community.document_loaders import PyPDFLoader, TextLoader +from langchain_community.docstore.document import Document +from typing import * +from utils.path_tool import get_abs_path +``` + +### utils/path_tool.py + +```python +import os +``` + +--- + +## 四、requirements.txt 参考 + +``` +langchain>=0.3.0 +langchain-core>=0.3.0 +langchain-community>=0.3.0 +langchain-chroma>=0.1.0 +langchain-text-splitters>=0.3.0 +langgraph>=0.2.0 +streamlit +pyyaml +pandas +``` + +--- + +## 五、包导入拓扑图 + +``` +标准库 (内置) +├── os, os.path +├── hashlib +├── logging +├── time +├── datetime +├── random +├── typing +├── abc +└── pathlib + +第三方包 (pip install) +├── streamlit (Web) +├── yaml (配置) +├── pandas (数据) +│ +└── LangChain 生态 + ├── langchain-core + │ ├── tools (tool) + │ ├── prompts (PromptTemplate) + │ ├── output_parsers (StrOutputParser) + │ ├── messages (ToolMessage) + │ └── embeddings (Embeddings) + │ + ├── langchain + │ ├── agents (create_agent, AgentState) + │ └── agents.middleware + │ + ├── langchain-community + │ ├── chat_models.tongyi (ChatTongyi) + │ ├── embeddings (DashScopeEmbeddings) + │ ├── document_loaders (PyPDFLoader, TextLoader) + │ └── docstore.document (Document) + │ + ├── langchain-chroma (Chroma) + │ + └── langchain-text-splitters + └── RecursiveCharacterTextSplitter + +LangGraph + ├── types (Command) + └── runtime (Runtime) +``` diff --git a/docs/INTERVIEW_PREP.md b/docs/INTERVIEW_PREP.md new file mode 100644 index 0000000..8d55e09 --- /dev/null +++ b/docs/INTERVIEW_PREP.md @@ -0,0 +1,387 @@ +# 面试知识点总结 + +> 基于本项目的技术栈,总结面试常问知识点 + +--- + +## 一、LangChain 核心知识点 + +### 1.1 LangChain Agent 机制 + +#### Q1: 什么是 LangChain Agent? 它与 Chain 的区别? + +| 特性 | Chain | Agent | +|------|-------|-------| +| 执行方式 | 固定流程,按顺序执行 | 动态决策,自主选择下一步 | +| 工具调用 | 预定义,需手动编写 | 自动判断是否调用工具 | +| 适用场景 | 固定流程 (如 RAG) | 需要推理和决策的场景 | + +**项目中的应用**: +```python +# 使用 create_agent 创建 Agent +agent = create_agent( + model=ChatTongyi(model="qwen3-max"), + tools=[rag_summarize, get_weather, get_user_id], + system_prompt="你是一个智能助手" +) +``` + +#### Q2: 解释 ReAct 框架在 Agent 中的应用 + +**ReAct = Reasoning + Acting** + +``` +Thought: 我需要知道用户所在城市的天气 +Action: get_weather +Action Input: 深圳 +Observation: 天气晴朗,26°C +Thought: 现在我有天气信息,可以回答用户问题了 +``` + +**项目中的体现**: +- 系统提示词明确要求遵循 ReAct 框架 +- Agent 自动完成 "思考→行动→观察→再思考" 循环 +- 最多支持 5 次工具调用 + +### 1.2 LangChain Middleware 中间件机制 + +#### Q3: LangChain 中间件是什么? 如何实现? + +LangChain 中间件是 LangGraph 提供的钩子机制,用于在 Agent 执行过程中注入自定义逻辑。 + +**项目中的三种中间件**: + +1. **wrap_tool_call** - 工具调用包装 +```python +@wrap_tool_call +def monitor_tool(request, handler): + # 工具调用前 + logger.info(f"执行工具: {request.tool_call['name']}") + result = handler(request) # 调用实际工具 + # 工具调用后 + return result +``` + +2. **before_model** - 模型调用前 +```python +@before_model +def log_before_model(state, runtime): + # 每次调用 LLM 前记录日志 + logger.info(f"即将调用模型,当前有 {len(state['messages'])} 条消息") + return None +``` + +3. **dynamic_prompt** - 动态提示词 +```python +@dynamic_prompt +def report_prompt_switch(request): + is_report = request.runtime.context.get("report", False) + if is_report: + return load_report_prompts() # 切换为报告生成 Prompt + return load_system_prompts() +``` + +#### Q4: 中间件的应用场景有哪些? + +| 场景 | 中间件类型 | +|------|-----------| +| 日志记录 | before_model, wrap_tool_call | +| 性能监控 | wrap_tool_call | +| 动态提示词 | dynamic_prompt | +| 权限控制 | wrap_tool_call | +| 结果缓存 | wrap_tool_call | + +--- + +## 二、RAG (检索增强生成) + +### 2.1 RAG 核心流程 + +``` +用户 query + │ + ▼ +┌─────────────────┐ +│ 向量检索 │ ← Chroma Retriever +└────────┬────────┘ + │ 返回 Top-K 相关文档 + ▼ +┌─────────────────┐ +│ 构建 Prompt │ ← 拼接 query + context +└────────┬────────┘ + │ + ▼ +┌─────────────────┐ +│ LLM 生成回答 │ ← 通义千问 +└────────┬────────┘ + │ + ▼ + 返回结果 +``` + +### 2.2 关键面试题 + +#### Q5: 为什么需要 RAG? 直接用 LLM 不可以吗? + +| 方案 | 优点 | 缺点 | +|------|------|------| +| 直接 LLM | 简单 | 知识截止、可能幻觉、无法访问私域知识 | +| RAG | 实时性、可引用私域知识、减少幻觉 | 增加复杂度、依赖检索质量 | + +#### Q6: RAG 中的关键环节有哪些? + +1. **文档加载**: PyPDFLoader, TextLoader +2. **文本分片**: RecursiveCharacterTextSplitter + - chunk_size: 每片大小 + - chunk_overlap: 重叠区域 (保持上下文) + - separators: 分隔符优先级 +3. **向量化**: Embedding 模型 +4. **向量存储**: Chroma +5. **相似度检索**: Cosine similarity, Top-K +6. **结果拼接**: Query + Context → Prompt + +#### Q7: 如何优化 RAG 效果? + +| 优化方向 | 方法 | +|----------|------| +| 检索质量 | 调整 chunk_size、overlap、使用 better embedding | +| 召回率 | 增加 Top-K、使用混合检索 | +| 排序rerank | 使用 rerank 模型二次排序 | +| Prompt 工程 | 优化 RAG Prompt 模板 | + +### 2.3 项目中的 RAG 实现 + +```python +# rag_service.py +class RagSummarizeService: + def rag_summarize(self, query: str) -> str: + # 1. 向量检索 + context_docs = self.retriever.invoke(query) + + # 2. 拼接上下文 + context = "" + for doc in context_docs: + context += f"[参考资料]: {doc.page_content} | {doc.metadata}\n" + + # 3. 调用 LLM 生成 + return self.chain.invoke({ + "input": query, + "context": context + }) +``` + +--- + +## 三、向量数据库 (Chroma) + +### 3.1 Chroma 核心概念 + +| 概念 | 说明 | +|------|------| +| Collection | 类似表,存储一类文档 | +| Embedding Function | 向量化函数 | +| Document | 包含 page_content 和 metadata | +| Retriever | 检索器,支持相似度搜索 | + +### 3.2 面试题 + +#### Q8: Chroma 的优势? + +- 轻量级,易于部署 +- Python 原生,集成方便 +- 支持持久化存储 +- 与 LangChain 无缝集成 + +#### Q9: Chroma 与其他向量库 (Milvus/Pinecone) 的区别? + +| 特性 | Chroma | Milvus | Pinecone | +|------|--------|--------|----------| +| 部署方式 | 本地/嵌入 | 服务端 | SaaS | +| 规模 | 中小 | 大规模 | 大规模 | +| 成熟度 | 一般 | 高 | 高 | + +--- + +## 四、Streamlit Web 开发 + +### 4.1 项目中的应用 + +```python +# app.py +import streamlit as st + +st.title("智扫通智能机器人客服") + +# 会话状态管理 +if "agent" not in st.session_state: + st.session_state["agent"] = ReactAgent() + +# 聊天记录 +for message in st.session_state["message"]: + st.chat_message(message["role"]).write(message["content"]) + +# 用户输入 +prompt = st.chat_input() + +# 流式输出 +if prompt: + stream = agent.excute_stream(prompt) + st.chat_message("assistant").write_stream(capture(stream)) +``` + +### 4.2 关键面试题 + +#### Q10: Streamlit 的核心机制? + +- **声明式 UI**: 通过 st.xxx() 声明组件 +- **脚本式**: 每次交互重新运行整个脚本 +- **状态管理**: session_state 保持会话状态 +- **热重载**: 修改代码自动刷新 + +#### Q11: 如何实现流式输出? + +```python +# 方法1: write_stream +st.write_stream(generator_function) + +# 方法2: 自定义 (本项目使用) +def capture(generator, cache_list): + for chunk in generator: + cache_list.append(chunk) + for char in chunk: + time.sleep(0.05) # 模拟打字效果 + yield char +``` + +--- + +## 五、设计模式 + +### 5.1 工厂模式 (Factory Pattern) + +```python +# model/factory.py +class BaseModelFactory(ABC): + @abstractmethod + def generator(self) -> Optional[Embeddings | BaseChatModel]: + pass + +class ChatModelFactory(BaseModelFactory): + def generator(self) -> Optional[BaseChatModel]: + return ChatTongyi(model=rag_conf["chat_model_name"]) + +class EmbeddingsFactory(BaseModelFactory): + def generator(self) -> Optional[Embeddings]: + return DashScopeEmbeddings(model=rag_conf["embeddings_model_name"]) +``` + +**好处**: 统一创建入口,便于后续更换模型 + +### 5.2 配置中心化 + +所有配置集中在 config/ 目录的 YAML 文件中: +- rag.yaml: 模型配置 +- chroma.yaml: 向量库配置 +- agent.yaml: Agent 配置 +- prompts.yaml: Prompt 路径配置 + +### 5.3 中间件模式 + +利用装饰器和钩子实现横切关注点: +- 日志 +- 监控 +- 动态提示词切换 + +--- + +## 六、工程实践 + +### 6.1 日志管理 + +```python +# utils/logger_handler.py +def get_logger(name: str = "Agent"): + logger = logging.getLogger(name) + # 双写: 控制台 + 文件 + console_handler = logging.StreamHandler() + file_handler = logging.FileHandler(log_file, encoding='utf-8') + return logger +``` + +### 6.2 路径管理 + +```python +# utils/path_tool.py +def get_project_root(): + cur_file = os.path.abspath(__file__) + proj_dir = os.path.dirname(os.path.dirname(cur_file)) + return proj_dir + +def get_abs_path(relative_path): + return os.path.join(get_project_root(), relative_path) +``` + +### 6.3 MD5 去重 + +```python +# vector_store.py +# 通过 MD5 避免重复加载文档 +md5_hex = get_file_md5_hex(path) +if check_md5_hex(md5_hex): + continue # 已存在,跳过 +self.vector_store.add_documents(split_doc) +save_md5(md5_hex) +``` + +--- + +## 七、LLM & Embedding + +### 7.1 通义千问 (Qwen) + +- **模型**: qwen3-max (阿里云) +- **调用**: langchain_community.chat_models.tongyi.ChatTongyi + +### 7.2 DashScope Embedding + +- **模型**: text-embedding-v4 +- **用途**: 将文本转为向量 +- **调用**: langchain_community.embeddings.DashScopeEmbeddings + +--- + +## 八、常见面试扩展问题 + +### Q12: 如何保证 Agent 工具调用的安全性? + +1. **工具入参校验**: Pydantic 类型提示 +2. **调用次数限制**: 最多 N 次 +3. **工具白名单**: 只允许调用指定工具 +4. **中间件监控**: 记录所有调用 + +### Q13: Agent 如何实现"思考过程"可视化? + +```python +# 项目中的实现 +for chunk in res: + last_msg = chunk["messages"][-1] + if last_msg.tool_calls: + # 显示思考过程 + print(f"工具调用: {last_msg.tool_calls}") +``` + +### Q14: RAG 召回率低怎么排查? + +1. 检查 chunk_size 是否合适 +2. 检查 embedding 质量 +3. 查看检索到的文档是否相关 +4. 调整 Top-K 值 +5. 检查分片是否有意义 (避免切断句子) + +### Q15: 生产环境部署注意什么? + +1. **API 限流**: 添加重试机制 +2. **错误处理**: 工具调用失败处理 +3. **日志**: 完整日志记录 +4. **监控**: 调用次数、耗时监控 +5. **缓存**: 热门 query 缓存结果 diff --git a/docs/LANGCHAIN_PACKAGE_MAP.md b/docs/LANGCHAIN_PACKAGE_MAP.md new file mode 100644 index 0000000..6dbe2fc --- /dev/null +++ b/docs/LANGCHAIN_PACKAGE_MAP.md @@ -0,0 +1,200 @@ +# LangChain 包地图 (Package Map) + +> 本项目使用的 LangChain 相关包一览,按功能模块分类 + +--- + +## 1. 核心包 (Core Packages) + +### langchain-core +| 类/函数 | 导入路径 | 用途 | +|---------|----------|------| +| `tool` | `langchain_core.tools` | 装饰器方式定义 Agent 工具 | +| `Embeddings` | `langchain_core.embeddings` | Embedding 模型抽象基类 | +| `BaseChatModel` | `langchain_core.chat_models` | 聊天模型抽象基类 | +| `PromptTemplate` | `langchain_core.prompts` | Prompt 模板构建 | +| `StrOutputParser` | `langchain_core.output_parsers` | 输出解析为字符串 | +| `Document` | `langchain_core.documents` | 文档对象 | +| `ToolMessage` | `langchain_core.messages` | 工具返回消息 | +| `AIMessage` | `langchain_core.messages` | AI 消息对象 | + +### langchain +| 类/函数 | 导入路径 | 用途 | +|---------|----------|------| +| `create_agent` | `langchain.agents` | 创建 LangChain Agent | +| `AgentState` | `langchain.agents` | Agent 状态定义 | +| `wrap_tool_call` | `langchain.agents.middleware` | 工具调用包装器 | +| `before_model` | `langchain.agents.middleware` | 模型调用前钩子 | +| `dynamic_prompt` | `langchain.agents.middleware` | 动态提示词装饰器 | +| `ModelRequest` | `langchain.agents.middleware` | 模型请求对象 | + +--- + +## 2. 社区包 (Community Packages) + +### langchain-community +| 类/函数 | 导入路径 | 用途 | +|---------|----------|------| +| `ChatTongyi` | `langchain_community.chat_models.tongyi` | 通义千问模型 | +| `BaseChatModel` | `langchain_community.chat_models` | 社区版聊天模型基类 | +| `DashScopeEmbeddings` | `langchain_community.embeddings` | 阿里 DashScope Embedding | +| `PyPDFLoader` | `langchain_community.document_loaders` | PDF 文件加载 | +| `TextLoader` | `langchain_community.document_loaders` | TXT 文件加载 | +| `Document` | `langchain_community.docstore.document` | 社区版文档对象 | + +--- + +## 3. 特定集成包 (Integration Packages) + +### langchain-chroma +| 类/函数 | 导入路径 | 用途 | +|---------|----------|------| +| `Chroma` | `langchain_chroma` | Chroma 向量数据库 | + +### langchain-text-splitters +| 类/函数 | 导入路径 | 用途 | +|---------|----------|------| +| `RecursiveCharacterTextSplitter` | `langchain_text_splitters` | 递归文本分片器 | + +--- + +## 4. LangGraph 相关包 + +### langgraph +| 类/函数 | 导入路径 | 用途 | +|---------|----------|------| +| `Command` | `langgraph.types` | LangGraph 命令对象 | +| `Runtime` | `langgraph.runtime` | LangGraph 运行时 | +| `ToolCallRequest` | `langchain.tools.tool_node` | 工具调用请求 | + +--- + +## 5. 包依赖关系图 + +``` +┌─────────────────────────────────────────────────────────────────┐ +│ 用户代码 (app.py) │ +└─────────────────────────────┬───────────────────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────────────────────────────┐ +│ langchain.agents │ +│ (create_agent, middleware) │ +└───────────────┬─────────────────────┬───────────────────────────┘ + │ │ + ▼ ▼ +┌───────────────────────────┐ ┌───────────────────────────────────┐ +│ langchain-core │ │ langchain-community │ +│ - tools (tool) │ │ - chat_models.tongyi (ChatTongyi)│ +│ - prompts (PromptTemplate)│ │ - embeddings (DashScope) │ +│ - output_parsers │ │ - document_loaders │ +│ - messages │ │ - docstore.document │ +└───────────────┬───────────┘ └───────────────┬───────────────────┘ + │ │ + ▼ ▼ +┌───────────────────────────┐ ┌───────────────────────────────────┐ +│ langchain-text-splitters│ │ langchain-chroma │ +│ (RecursiveCharacterText │ │ (Chroma) │ +│ Splitter) │ │ │ +└───────────────────────────┘ └───────────────────────────────────┘ + │ + ▼ + ┌─────────────┐ + │ Chroma DB │ + └─────────────┘ +``` + +--- + +## 6. 项目中的实际使用示例 + +### 6.1 工具定义 +```python +from langchain_core.tools import tool + +@tool(description="查询天气") +def get_weather(city: str) -> str: + return f"{city}天气晴朗" +``` + +### 6.2 Agent 创建 +```python +from langchain.agents import create_agent +from langchain_community.chat_models.tongyi import ChatTongyi + +agent = create_agent( + model=ChatTongyi(model="qwen3-max"), + tools=[get_weather], + system_prompt="你是一个智能助手" +) +``` + +### 6.3 RAG Chain +```python +from langchain_core.output_parsers import StrOutputParser +from langchain_core.prompts import PromptTemplate + +chain = prompt_text | model | StrOutputParser() +``` + +### 6.4 向量存储 +```python +from langchain_chroma import Chroma +from langchain_community.embeddings import DashScopeEmbeddings + +vector_store = Chroma( + collection_name="agent", + embedding_function=DashScopeEmbeddings(model="text-embedding-v4"), + persist_directory="chroma_db" +) +``` + +### 6.5 文档加载 +```python +from langchain_community.document_loaders import PyPDFLoader, TextLoader + +pdf_docs = PyPDFLoader("file.pdf").load() +txt_docs = TextLoader("file.txt", encoding="utf-8").load() +``` + +### 6.6 文本分片 +```python +from langchain_text_splitters import RecursiveCharacterTextSplitter + +splitter = RecursiveCharacterTextSplitter( + chunk_size=200, + chunk_overlap=20, + separators=["\n\n", "\n", ".", "!", "?"] +) +``` + +--- + +## 7. 包版本要求参考 + +``` +langchain>=0.3.0 +langchain-core>=0.3.0 +langchain-community>=0.3.0 +langchain-chroma>=0.1.0 +langchain-text-splitters>=0.3.0 +langgraph>=0.2.0 +``` + +--- + +## 8. QA + +### Q1: langchain-core 和 langchain-community 的区别? +- **langchain-core**: LangChain 核心抽象接口,不包含具体实现 +- **langchain-community**: 第三方集成 (如通义千问、DashScope) + +### Q2: 为什么选择 langchain-chroma 而不是直接用 chromadb? +- LangChain 封装了统一的接口,便于后续更换向量数据库 +- 与 LangChain Chain/Agent 更好地集成 + +### Q3: middleware 机制的实现原理? +- 基于 LangGraph 的钩子系统 +- `wrap_tool_call`: 包装工具调用前后逻辑 +- `before_model`: 模型调用前的预处理 +- `dynamic_prompt`: 动态生成提示词 diff --git a/docs/PROJECT_OUTLINE.md b/docs/PROJECT_OUTLINE.md new file mode 100644 index 0000000..01f7f5a --- /dev/null +++ b/docs/PROJECT_OUTLINE.md @@ -0,0 +1,276 @@ +# 智扫通智能客服项目 - 项目大纲 + +## 1. 项目概述 + +**项目名称**: 智扫通智能机器人客服 + +**项目类型**: 基于 LangChain + RAG + Agent 的智能问答系统 + +**核心功能**: +- 提供扫地机器人/扫拖一体机器人的专业智能客服 +- 支持 ReAct 思考框架的 Agent 自主工具调用 +- 基于向量检索(RAG)的专业知识库问答 +- 个性化用户报告生成 + +**目标用户**: 扫地机器人用户 + +--- + +## 2. 技术架构 + +### 2.1 技术栈 + +| 层级 | 技术/框架 | 用途 | +|------|----------|------| +| 前端 | Streamlit | Web 交互界面 | +| AI Agent | LangChain + LangGraph | Agent 推理与工具调用 | +| LLM | 通义千问 (qwen3-max) | 大语言模型 | +| 向量数据库 | Chroma | 知识向量存储与检索 | +| Embedding | DashScope (text-embedding-v4) | 文本向量化 | +| 配置管理 | YAML | 配置文件管理 | + +### 2.2 系统架构图 + +``` +┌─────────────────────────────────────────────────────────┐ +│ Streamlit Web UI │ +└─────────────────────┬───────────────────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────────────────────┐ +│ ReactAgent (Agent) │ +│ ┌─────────────────────────────────────────────────┐ │ +│ │ ReAct 思考框架 │ │ +│ │ Thought → Action → Observation → ... │ │ +│ └─────────────────────────────────────────────────┘ │ +│ │ │ +│ ┌─────────────┼─────────────┐ │ +│ ▼ ▼ ▼ │ +│ ┌──────────────┐ ┌───────────┐ ┌──────────────┐ │ +│ │ RAG工具 │ │ 天气工具 │ │ 用户信息工具 │ │ +│ │ rag_summarize│ │ get_weather│ │ get_user_id │ │ +│ └──────────────┘ └───────────┘ └──────────────┘ │ +│ │ │ +│ ┌──────────────────────────────────────────────────┐ │ +│ │ Middleware 中间件 │ │ +│ │ monitor_tool | log_before_model | prompt_switch│ │ +│ └──────────────────────────────────────────────────┘ │ +└─────────────────────┬───────────────────────────────────┘ + │ + ┌───────────┴───────────┐ + ▼ ▼ +┌─────────────────┐ ┌─────────────────────┐ +│ VectorStore │ │ 外部数据源 │ +│ (Chroma DB) │ │ (CSV 用户记录) │ +└─────────────────┘ └─────────────────────┘ +``` + +--- + +## 3. 目录结构 + +``` +agent_proj/ +├── agent/ # Agent 核心模块 +│ ├── tools/ +│ │ ├── agent_tools.py # Agent 工具定义 +│ │ └── middleware.py # 中间件实现 +│ └── react_agent.py # ReAct Agent 封装 +│ +├── config/ # 配置文件 +│ ├── agent.yaml # Agent 配置 +│ ├── chroma.yaml # Chroma 向量库配置 +│ ├── prompts.yaml # Prompt 路径配置 +│ └── rag.yaml # RAG 模型配置 +│ +├── data/ # 数据目录 +│ ├── external/ +│ │ └── records.csv # 用户使用记录 +│ └── 知识库文件 (pdf/txt) # RAG 知识库 +│ +├── model/ # 模型工厂 +│ └── factory.py # LLM/Embedding 模型工厂 +│ +├── prompts/ # Prompt 模板 +│ ├── main_prompt.txt # 主系统 Prompt +│ ├── rag_summarize.txt # RAG 总结 Prompt +│ └── report_prompt.txt # 报告生成 Prompt +│ +├── rag/ # RAG 服务 +│ ├── rag_service.py # RAG 总结服务 +│ └── vector_store.py # 向量存储服务 +│ +├── utils/ # 工具模块 +│ ├── config_handler.py # 配置加载器 +│ ├── file_handler.py # 文件处理 +│ ├── logger_handler.py # 日志管理 +│ ├── path_tool.py # 路径工具 +│ └── prompt_loader.py # Prompt 加载器 +│ +├── chroma_db/ # Chroma 向量数据库 +│ +├── logs/ # 日志目录 +│ +├── app.py # Streamlit 主应用 +├── 01_Agent.py # Agent 基础示例 +├── 02_Stream.py # Stream 流式输出示例 +├── 03_ReAct.py # ReAct 框架示例 +└── 04_middle_ware.py # 中间件示例 +``` + +--- + +## 4. 核心模块详解 + +### 4.1 Agent 模块 (agent/) + +#### react_agent.py +- **职责**: 封装 LangChain Agent,提供流式输出能力 +- **核心方法**: `excute_stream(query)` - 流式执行用户查询 + +#### agent_tools.py +- **职责**: 定义 Agent 可调用的工具 +- **工具列表**: + - `rag_summarize`: 向量库检索专业资料 + - `get_weather`: 查询城市天气 + - `get_user_location`: 获取用户所在城市 + - `get_user_id`: 获取用户ID + - `get_current_month`: 获取当前月份 + - `fetch_external_data`: 获取外部用户使用记录 + - `fill_context_for_report`: 触发报告生成上下文 + +#### middleware.py +- **职责**: 实现 Agent 中间件 +- **中间件列表**: + - `monitor_tool`: 工具调用监控 + - `log_before_model`: 模型调用前日志 + - `repoet_prompt_switch`: 动态提示词切换 + +### 4.2 RAG 模块 (rag/) + +#### vector_store.py +- **职责**: 向量存储与检索 +- **功能**: + - 文档加载 (PDF/TXT) + - 文本分片 (RecursiveCharacterTextSplitter) + - 向量入库 (Chroma) + - 相似度检索 (Retriever) + +#### rag_service.py +- **职责**: RAG 总结服务 +- **流程**: 用户查询 → 向量检索 → Prompt 模板 → LLM 总结 → 返回结果 + +### 4.3 模型工厂 (model/factory.py) +- **ChatModelFactory**: 创建通义千问聊天模型 +- **EmbeddingsFactory**: 创建 DashScope Embedding 模型 + +### 4.4 工具模块 (utils/) + +| 模块 | 功能 | +|------|------| +| config_handler | YAML 配置文件加载 | +| logger_handler | 日志管理 (双写: 控制台+文件) | +| prompt_loader | Prompt 模板加载 | +| file_handler | PDF/TXT 文件加载, MD5 计算 | +| path_tool | 绝对路径获取 | + +--- + +## 5. 数据流 + +### 5.1 知识库构建流程 + +``` +知识库文件 (PDF/TXT) + │ + ▼ + 文件加载器 (PyPDFLoader/TextLoader) + │ + ▼ + 文本分片 (RecursiveCharacterTextSplitter) + │ + ▼ + 向量化 (DashScope Embeddings) + │ + ▼ + Chroma 向量库存储 + │ + ▼ + MD5 去重记录 +``` + +### 5.2 用户问答流程 + +``` +用户提问 + │ + ▼ +Streamlit UI 接收 + │ + ▼ +ReactAgent.excute_stream() + │ + ▼ +ReAct Agent 推理循环 + │ + ├─→ 判断是否需要调用工具 + ├─→ 选择工具 (RAG/天气/用户信息/外部数据) + ├─→ 执行工具获取结果 + ├─→ 观察结果,更新思考 + └─→ 生成最终回答 + │ + ▼ +流式输出到 UI +``` + +--- + +## 6. 配置说明 + +### 6.1 rag.yaml +```yaml +chat_model_name: "qwen3-max" # LLM 模型 +embeddings_model_name: "text-embedding-v4" # Embedding 模型 +``` + +### 6.2 chroma.yaml +```yaml +collection_name: "agent" # 向量库集合名 +persist_directory: "chroma_db" # 持久化目录 +k: 3 # 检索Top-K +chunk_size: 200 # 分片大小 +chunk_overlap: 20 # 分片重叠 +``` + +### 6.3 agent.yaml +```yaml +external_data_path: "data/external/records.csv" # 外部数据路径 +``` + +--- + +## 7. 运行方式 + +### 7.1 启动 Web 应用 +```bash +streamlit run app.py +``` + +### 7.2 知识库初始化 +```bash +python -m rag.vector_store +``` + +--- + +## 8. 面试要点总结 + +| 知识点 | 项目中的应用 | +|--------|--------------| +| LangChain Agent | create_agent, ReAct 框架 | +| LangGraph | 中间件机制, 动态提示词 | +| RAG | 向量检索, 文档分片, Chain 组合 | +| Chroma | 向量数据库存储与检索 | +| Streamlit | Web 前后端交互 | +| 中间件模式 | 工具调用监控, 动态 Prompt | +| 设计模式 | 工厂模式, 配置中心化 | diff --git a/lesson/01_Agent.py b/lesson/01_Agent.py new file mode 100644 index 0000000..01614ed --- /dev/null +++ b/lesson/01_Agent.py @@ -0,0 +1,26 @@ +from langchain.agents import create_agent +from langchain_community.chat_models.tongyi import ChatTongyi +from langchain_core.tools import tool + +@tool(description="查询天气") +def get_weather(): + return "晴天" + + +agent = create_agent( + model=ChatTongyi(model="qwen3-max"), + tools=[get_weather], + system_prompt="你是一个聊天助手,可以回答用户问题" +) + +res = agent.invoke( + { + "messages": [ + {"role": "user", "content": "明天深圳的天气如何"}, + ] + } +) + +for msg in res["messages"]: + print(f"{type(msg).__name__}: {msg.content}") + \ No newline at end of file diff --git a/lesson/02_Stream.py b/lesson/02_Stream.py new file mode 100644 index 0000000..9092556 --- /dev/null +++ b/lesson/02_Stream.py @@ -0,0 +1,37 @@ +from langchain.agents import create_agent +from langchain_community.chat_models.tongyi import ChatTongyi +from langchain_core.tools import tool + + +@tool(description="查询股票价格") +def get_price(name: str) -> str: + return f"股票{name}的价格是20元" + + +@tool(description="查询股票信息") +def get_info(name: str) -> str: + return f"股票{name}是一家A股上市公司" + + +agent = create_agent( + model=ChatTongyi(model="qwen3-max"), + tools=[get_price, get_info], + system_prompt="你是一个智能助手,可以回答股票相关问题,请告知我思考过程,让我知道你为什么调用某个工具" +) + +res = agent.stream( + {"messages": [{ + "role": "user", "content": "kk公司股价多少,并介绍一下" + }]}, + stream_mode="values" +) + +for chunk in res: + last_msg = chunk["messages"][-1] + if last_msg.content: + print(type(last_msg).__name__, last_msg.content) + + if type(last_msg).__name__ == "AIMessage": + if last_msg.tool_calls: + tool_list = [tc['name'] for tc in last_msg.tool_calls] + print(f"工具调佣 {tool_list}") diff --git a/lesson/03_ReAct.py b/lesson/03_ReAct.py new file mode 100644 index 0000000..00c6485 --- /dev/null +++ b/lesson/03_ReAct.py @@ -0,0 +1,39 @@ +from langchain.agents import create_agent +from langchain_community.chat_models.tongyi import ChatTongyi +from langchain_core.tools import tool + + +@tool(description="获取体重,返回值整数,单位千克") +def get_weight() -> int: + return 93 + + +@tool(description="获取身高,返回值整数,单位厘米") +def get_height() -> int: + return 185 + + +agent = create_agent( + model=ChatTongyi(model="qwen3-max"), + tools=[get_height, get_weight], + system_prompt="""你是严格遵循ReAct框架的智能体,必须按[思考,行动,观察,再思考]的流程解决问题 + 每轮仅能思考并调用1个工具,禁止单词调用多个工具。并告知我你的思考过程,工具调用的原因,按思考、行动 + 、观察三个结构告知我""" +) + +res = agent.stream( + {"messages": [{ + "role": "user", "content": "计算我的BMI" + }]}, + stream_mode="values" +) + +for chunk in res: + last_msg = chunk["messages"][-1] + if last_msg.content: + print(type(last_msg).__name__, last_msg.content) + + if type(last_msg).__name__ == "AIMessage": + if last_msg.tool_calls: + tool_list = [tc['name'] for tc in last_msg.tool_calls] + print(f"工具调佣 {tool_list}") diff --git a/lesson/04_middle_ware.py b/lesson/04_middle_ware.py new file mode 100644 index 0000000..0c52cc2 --- /dev/null +++ b/lesson/04_middle_ware.py @@ -0,0 +1,70 @@ +""" +agent 前后 +model 前后 +工具 中 +模型 中 +""" + +from langchain.agents import create_agent, AgentState +from langchain.agents.middleware import before_agent, after_agent, before_model, after_model, wrap_model_call, \ + wrap_tool_call +from langchain_community.chat_models.tongyi import ChatTongyi +from langchain_core.tools import tool +from langgraph.runtime import Runtime + + +@tool(description="查询天气, 传入城市名称字符串,返回字符串天气信息") +def get_weather(city: str) -> str: + return f"{city} : 晴天" + + +@before_agent +def log_before_agent(state: AgentState, runtime: Runtime) -> None: + print(f"before agent: info_num: {len(state["messages"])}") + + +@after_agent +def log_after_agent(state: AgentState, runtime: Runtime) -> None: + print(f"after agent: info_num: {len(state["messages"])}") + + +@before_model +def log_before_model(state: AgentState, runtime: Runtime) -> None: + print(f"before model: info_num: {len(state["messages"])}") + + +@after_model +def log_after_model(state: AgentState, runtime: Runtime) -> None: + print(f"after model: info_num: {len(state["messages"])}") + + +@wrap_model_call +def model_call_hook(request, handler): + print(f"model call: {request}") + return handler(request) + + +@wrap_tool_call +def model_tool_hook(request, handler): + print(f"model tool: {request.tool_call['name']}") + print(f"args: {request.tool_call['args']}") + return handler(request) + +agent = create_agent( + model=ChatTongyi(model="qwen3-max"), + tools=[get_weather], + middleware=[model_call_hook, model_tool_hook, log_before_model, + log_after_model, log_before_agent, log_after_agent], + system_prompt="""你是严格遵循ReAct框架的智能体,必须按[思考,行动,观察,再思考]的流程解决问题 + 每轮仅能思考并调用1个工具,禁止单词调用多个工具。并告知我你的思考过程,工具调用的原因,按思考、行动 + 、观察三个结构告知我""" +) + +res = agent.stream( + {"messages": [{ + "role": "user", "content": "查询北京的天气" + }]}, + stream_mode="values" +) +for chunk in res: + print(chunk["messages"][-1].content) diff --git a/logs/Agent_20260301.log b/logs/Agent_20260301.log index 246f529..8369214 100644 --- a/logs/Agent_20260301.log +++ b/logs/Agent_20260301.log @@ -222,3 +222,167 @@ 2026-03-01 15:27:30,002 - Agent - INFO - middleware.py:23 - [tool minitor]工具rag_summarize调用成功 2026-03-01 15:27:30,003 - Agent - INFO - middleware.py:39 - [log_before_model]即将调用模型,带有17条消息 2026-03-01 15:27:30,005 - Agent - DEBUG - middleware.py:40 - [log_before_model]ToolMessage | 消息内容:参考资料中未提及扫地机器人电池保养的具体方法。 +2026-03-01 15:44:30,893 - Agent - INFO - middleware.py:39 - [log_before_model]即将调用模型,带有1条消息 +2026-03-01 15:44:30,894 - Agent - DEBUG - middleware.py:40 - [log_before_model]HumanMessage | 消息内容:你好 +2026-03-01 15:44:39,601 - Agent - INFO - middleware.py:39 - [log_before_model]即将调用模型,带有1条消息 +2026-03-01 15:44:39,601 - Agent - DEBUG - middleware.py:40 - [log_before_model]HumanMessage | 消息内容:你是谁 +2026-03-01 15:45:38,723 - Agent - INFO - middleware.py:39 - [log_before_model]即将调用模型,带有1条消息 +2026-03-01 15:45:38,725 - Agent - DEBUG - middleware.py:40 - [log_before_model]HumanMessage | 消息内容:在我当前的位置和气温下,机器人如何保养 +2026-03-01 15:45:42,109 - Agent - INFO - middleware.py:18 - [tool monitor]执行工具:get_user_location +2026-03-01 15:45:42,109 - Agent - INFO - middleware.py:19 - [tool monitor]传入参数:{} +2026-03-01 15:45:42,112 - Agent - INFO - middleware.py:23 - [tool minitor]工具get_user_location调用成功 +2026-03-01 15:45:42,113 - Agent - INFO - middleware.py:39 - [log_before_model]即将调用模型,带有3条消息 +2026-03-01 15:45:42,114 - Agent - DEBUG - middleware.py:40 - [log_before_model]ToolMessage | 消息内容:杭州 +2026-03-01 15:45:44,728 - Agent - INFO - middleware.py:18 - [tool monitor]执行工具:get_weather +2026-03-01 15:45:44,729 - Agent - INFO - middleware.py:19 - [tool monitor]传入参数:{'city': '杭州'} +2026-03-01 15:45:44,730 - Agent - INFO - middleware.py:23 - [tool minitor]工具get_weather调用成功 +2026-03-01 15:45:44,732 - Agent - INFO - middleware.py:39 - [log_before_model]即将调用模型,带有5条消息 +2026-03-01 15:45:44,733 - Agent - DEBUG - middleware.py:40 - [log_before_model]ToolMessage | 消息内容:城市杭州天气为晴天,温度为26摄氏度,湿度50%,南风1级,AQI21,最近6小时降雨概率极低 +2026-03-01 15:45:48,666 - Agent - INFO - middleware.py:18 - [tool monitor]执行工具:rag_summarize +2026-03-01 15:45:48,668 - Agent - INFO - middleware.py:19 - [tool monitor]传入参数:{'query': '扫地机器人在26度、湿度50%、晴天环境下的保养建议'} +2026-03-01 15:45:49,200 - Agent - INFO - rag_service.py:33 - [rag_summarize]: 召回了3条参考资料 +2026-03-01 15:45:54,201 - Agent - INFO - middleware.py:23 - [tool minitor]工具rag_summarize调用成功 +2026-03-01 15:45:54,202 - Agent - INFO - middleware.py:39 - [log_before_model]即将调用模型,带有7条消息 +2026-03-01 15:45:54,202 - Agent - DEBUG - middleware.py:40 - [log_before_model]ToolMessage | 消息内容:在26度、湿度50%、晴天环境下,属于常规室内环境,无特殊环境风险。根据参考资料,应每日使用后用干软布擦拭机身外壳,去除灰尘和水渍;每次清扫完成后及时清理防撞条缝隙的毛发和线头;若涉及拖地功能,需确保拖布和水箱清洁,避免污渍残留。该环境未在参考资料中被特别归类,因此按通用基础维护执行即可。 +2026-03-01 15:46:13,483 - Agent - INFO - middleware.py:39 - [log_before_model]即将调用模型,带有1条消息 +2026-03-01 15:46:13,485 - Agent - DEBUG - middleware.py:40 - [log_before_model]HumanMessage | 消息内容:生成我的报告 +2026-03-01 15:46:15,920 - Agent - INFO - middleware.py:18 - [tool monitor]执行工具:get_user_id +2026-03-01 15:46:15,920 - Agent - INFO - middleware.py:19 - [tool monitor]传入参数:{} +2026-03-01 15:46:15,921 - Agent - INFO - middleware.py:23 - [tool minitor]工具get_user_id调用成功 +2026-03-01 15:46:15,923 - Agent - INFO - middleware.py:39 - [log_before_model]即将调用模型,带有3条消息 +2026-03-01 15:46:15,923 - Agent - DEBUG - middleware.py:40 - [log_before_model]ToolMessage | 消息内容:1008 +2026-03-01 15:46:18,263 - Agent - INFO - middleware.py:18 - [tool monitor]执行工具:get_current_month +2026-03-01 15:46:18,263 - Agent - INFO - middleware.py:19 - [tool monitor]传入参数:{} +2026-03-01 15:46:18,264 - Agent - INFO - middleware.py:23 - [tool minitor]工具get_current_month调用成功 +2026-03-01 15:46:18,266 - Agent - INFO - middleware.py:39 - [log_before_model]即将调用模型,带有5条消息 +2026-03-01 15:46:18,266 - Agent - DEBUG - middleware.py:40 - [log_before_model]ToolMessage | 消息内容:2025-09 +2026-03-01 15:46:23,075 - Agent - INFO - middleware.py:18 - [tool monitor]执行工具:fill_context_for_report +2026-03-01 15:46:23,076 - Agent - INFO - middleware.py:19 - [tool monitor]传入参数:{} +2026-03-01 15:46:23,077 - Agent - INFO - middleware.py:23 - [tool minitor]工具fill_context_for_report调用成功 +2026-03-01 15:46:23,078 - Agent - INFO - middleware.py:39 - [log_before_model]即将调用模型,带有7条消息 +2026-03-01 15:46:23,079 - Agent - DEBUG - middleware.py:40 - [log_before_model]ToolMessage | 消息内容:fill_context_for_report已调用 +2026-03-01 15:46:26,814 - Agent - INFO - middleware.py:18 - [tool monitor]执行工具:fetch_external_data +2026-03-01 15:46:26,815 - Agent - INFO - middleware.py:19 - [tool monitor]传入参数:{'user_id': '1008', 'month': '2025-09'} +2026-03-01 15:46:26,817 - Agent - INFO - middleware.py:23 - [tool minitor]工具fetch_external_data调用成功 +2026-03-01 15:46:26,819 - Agent - INFO - middleware.py:39 - [log_before_model]即将调用模型,带有9条消息 +2026-03-01 15:46:26,819 - Agent - DEBUG - middleware.py:40 - [log_before_model]ToolMessage | 消息内容:{"特征": "100㎡三居 | 三口之家 | 大理石", "效率": "覆盖率:86%\\n餐桌区域漏扫:1次/天\\n避障成功率:90%", "耗材": "主刷磨损:轻度\\n水箱加水:每日2次", "对比": "大理石地面清洁效果低于同类15%"} +2026-03-01 15:46:29,637 - Agent - INFO - middleware.py:18 - [tool monitor]执行工具:rag_summarize +2026-03-01 15:46:29,638 - Agent - INFO - middleware.py:19 - [tool monitor]传入参数:{'query': '大理石地面扫地机器人使用建议和保养'} +2026-03-01 15:46:30,033 - Agent - INFO - rag_service.py:33 - [rag_summarize]: 召回了3条参考资料 +2026-03-01 15:46:36,226 - Agent - INFO - middleware.py:23 - [tool minitor]工具rag_summarize调用成功 +2026-03-01 15:46:36,228 - Agent - INFO - middleware.py:39 - [log_before_model]即将调用模型,带有11条消息 +2026-03-01 15:46:36,229 - Agent - DEBUG - middleware.py:40 - [log_before_model]ToolMessage | 消息内容:在大理石地面使用扫地机器人时,拖地后应及时清理机器人底部水渍,每月对拖布支架进行除垢,防止水垢附着。 +2026-03-01 15:46:38,897 - Agent - INFO - middleware.py:18 - [tool monitor]执行工具:rag_summarize +2026-03-01 15:46:38,898 - Agent - INFO - middleware.py:19 - [tool monitor]传入参数:{'query': '扫地机器人餐桌区域漏扫问题解决方案'} +2026-03-01 15:46:42,325 - Agent - INFO - rag_service.py:33 - [rag_summarize]: 召回了3条参考资料 +2026-03-01 15:46:45,608 - Agent - INFO - middleware.py:23 - [tool minitor]工具rag_summarize调用成功 +2026-03-01 15:46:45,610 - Agent - INFO - middleware.py:39 - [log_before_model]即将调用模型,带有13条消息 +2026-03-01 15:46:45,611 - Agent - DEBUG - middleware.py:40 - [log_before_model]ToolMessage | 消息内容:针对扫地机器人餐桌区域漏扫问题,可采取以下措施:检查是否设置了禁区,重新建图或手动遥控补扫;确认是否开启沿边清扫模式;检查边刷是否磨损或被缠绕,并进行清理或更换;确保地图完整且机器人电量充足。 +2026-03-01 15:46:48,105 - Agent - INFO - middleware.py:18 - [tool monitor]执行工具:rag_summarize +2026-03-01 15:46:48,106 - Agent - INFO - middleware.py:19 - [tool monitor]传入参数:{'query': '扫地机器人主刷保养和更换周期'} +2026-03-01 15:46:49,487 - Agent - INFO - rag_service.py:33 - [rag_summarize]: 召回了3条参考资料 +2026-03-01 15:46:54,623 - Agent - INFO - middleware.py:23 - [tool minitor]工具rag_summarize调用成功 +2026-03-01 15:46:54,628 - Agent - INFO - middleware.py:39 - [log_before_model]即将调用模型,带有15条消息 +2026-03-01 15:46:54,628 - Agent - DEBUG - middleware.py:40 - [log_before_model]ToolMessage | 消息内容:主刷(滚刷)需每周清理毛发,每月用清水冲洗;一般每3-6个月更换一次,若出现磨损、变形、开裂或脱落应立即更换。在宠物家庭等高损耗环境中,耗材更换周期应缩短50%。 +2026-03-01 15:48:17,528 - Agent - INFO - middleware.py:39 - [log_before_model]即将调用模型,带有1条消息 +2026-03-01 15:48:17,530 - Agent - DEBUG - middleware.py:40 - [log_before_model]HumanMessage | 消息内容: +2026-03-01 15:48:52,658 - Agent - INFO - middleware.py:39 - [log_before_model]即将调用模型,带有1条消息 +2026-03-01 15:48:52,660 - Agent - DEBUG - middleware.py:40 - [log_before_model]HumanMessage | 消息内容:你好 +2026-03-01 15:48:56,097 - Agent - INFO - middleware.py:39 - [log_before_model]即将调用模型,带有1条消息 +2026-03-01 15:48:56,098 - Agent - DEBUG - middleware.py:40 - [log_before_model]HumanMessage | 消息内容:生成我的报告 +2026-03-01 15:48:58,992 - Agent - INFO - middleware.py:18 - [tool monitor]执行工具:fill_context_for_report +2026-03-01 15:48:58,993 - Agent - INFO - middleware.py:19 - [tool monitor]传入参数:{} +2026-03-01 15:48:58,995 - Agent - INFO - middleware.py:23 - [tool minitor]工具fill_context_for_report调用成功 +2026-03-01 15:48:58,996 - Agent - INFO - middleware.py:39 - [log_before_model]即将调用模型,带有3条消息 +2026-03-01 15:48:58,996 - Agent - DEBUG - middleware.py:40 - [log_before_model]ToolMessage | 消息内容:fill_context_for_report已调用 +2026-03-01 15:49:00,483 - Agent - INFO - middleware.py:18 - [tool monitor]执行工具:get_user_id +2026-03-01 15:49:00,484 - Agent - INFO - middleware.py:19 - [tool monitor]传入参数:{} +2026-03-01 15:49:00,485 - Agent - INFO - middleware.py:23 - [tool minitor]工具get_user_id调用成功 +2026-03-01 15:49:00,485 - Agent - INFO - middleware.py:18 - [tool monitor]执行工具:get_current_month +2026-03-01 15:49:00,485 - Agent - INFO - middleware.py:19 - [tool monitor]传入参数:{} +2026-03-01 15:49:00,486 - Agent - INFO - middleware.py:23 - [tool minitor]工具get_current_month调用成功 +2026-03-01 15:49:00,487 - Agent - INFO - middleware.py:39 - [log_before_model]即将调用模型,带有6条消息 +2026-03-01 15:49:00,487 - Agent - DEBUG - middleware.py:40 - [log_before_model]ToolMessage | 消息内容:2025-09 +2026-03-01 15:49:02,870 - Agent - INFO - middleware.py:18 - [tool monitor]执行工具:fetch_external_data +2026-03-01 15:49:02,870 - Agent - INFO - middleware.py:19 - [tool monitor]传入参数:{'user_id': '1004', 'month': '2025-09'} +2026-03-01 15:49:02,873 - Agent - INFO - middleware.py:23 - [tool minitor]工具fetch_external_data调用成功 +2026-03-01 15:49:02,875 - Agent - INFO - middleware.py:39 - [log_before_model]即将调用模型,带有8条消息 +2026-03-01 15:49:02,875 - Agent - DEBUG - middleware.py:40 - [log_before_model]ToolMessage | 消息内容:{"特征": "85㎡ | 2猫 | 混合地面", "效率": "猫砂泼洒处理:8次/月\\n自动回充成功率:88%", "耗材": "主刷缠绕:中度+\\n滤网寿命:剩余60天", "对比": "防缠绕主刷生效+清洁效率提升8%"} +2026-03-01 15:49:04,864 - Agent - INFO - middleware.py:18 - [tool monitor]执行工具:rag_summarize +2026-03-01 15:49:04,864 - Agent - INFO - middleware.py:19 - [tool monitor]传入参数:{'query': '多猫家庭扫地机器人维护建议'} +2026-03-01 15:49:06,277 - Agent - INFO - rag_service.py:33 - [rag_summarize]: 召回了3条参考资料 +2026-03-01 15:49:09,648 - Agent - INFO - middleware.py:23 - [tool minitor]工具rag_summarize调用成功 +2026-03-01 15:49:09,651 - Agent - INFO - middleware.py:39 - [log_before_model]即将调用模型,带有10条消息 +2026-03-01 15:49:09,652 - Agent - DEBUG - middleware.py:40 - [log_before_model]ToolMessage | 消息内容:多猫家庭使用扫地机器人需每次清扫后全面清理主刷、尘盒和拖布,每日擦拭机身外壳并检查边刷是否卡顿,每周进行除味消毒,耗材更换周期缩短50%;若机器人沾到宠物粪便,应立即用湿巾清理并用中性洗涤剂擦拭。 +2026-03-01 15:50:29,548 - Agent - INFO - middleware.py:39 - [log_before_model]即将调用模型,带有1条消息 +2026-03-01 15:50:29,550 - Agent - DEBUG - middleware.py:40 - [log_before_model]HumanMessage | 消息内容:你是谁 +2026-03-01 15:51:10,506 - Agent - INFO - middleware.py:39 - [log_before_model]即将调用模型,带有1条消息 +2026-03-01 15:51:10,506 - Agent - DEBUG - middleware.py:40 - [log_before_model]HumanMessage | 消息内容:你是谁 +2026-03-01 15:51:17,954 - Agent - INFO - middleware.py:39 - [log_before_model]即将调用模型,带有1条消息 +2026-03-01 15:51:17,954 - Agent - DEBUG - middleware.py:40 - [log_before_model]HumanMessage | 消息内容:生成试用报告 +2026-03-01 15:51:20,574 - Agent - INFO - middleware.py:18 - [tool monitor]执行工具:get_user_id +2026-03-01 15:51:20,576 - Agent - INFO - middleware.py:19 - [tool monitor]传入参数:{} +2026-03-01 15:51:20,577 - Agent - INFO - middleware.py:23 - [tool minitor]工具get_user_id调用成功 +2026-03-01 15:51:20,635 - Agent - INFO - middleware.py:39 - [log_before_model]即将调用模型,带有3条消息 +2026-03-01 15:51:20,635 - Agent - DEBUG - middleware.py:40 - [log_before_model]ToolMessage | 消息内容:1005 +2026-03-01 15:51:23,886 - Agent - INFO - middleware.py:18 - [tool monitor]执行工具:get_current_month +2026-03-01 15:51:23,887 - Agent - INFO - middleware.py:19 - [tool monitor]传入参数:{} +2026-03-01 15:51:23,888 - Agent - INFO - middleware.py:23 - [tool minitor]工具get_current_month调用成功 +2026-03-01 15:51:23,985 - Agent - INFO - middleware.py:39 - [log_before_model]即将调用模型,带有5条消息 +2026-03-01 15:51:23,985 - Agent - DEBUG - middleware.py:40 - [log_before_model]ToolMessage | 消息内容:2025-08 +2026-03-01 15:51:27,560 - Agent - INFO - middleware.py:18 - [tool monitor]执行工具:fill_context_for_report +2026-03-01 15:51:27,561 - Agent - INFO - middleware.py:19 - [tool monitor]传入参数:{} +2026-03-01 15:51:27,562 - Agent - INFO - middleware.py:23 - [tool minitor]工具fill_context_for_report调用成功 +2026-03-01 15:51:27,890 - Agent - INFO - middleware.py:39 - [log_before_model]即将调用模型,带有7条消息 +2026-03-01 15:51:27,891 - Agent - DEBUG - middleware.py:40 - [log_before_model]ToolMessage | 消息内容:fill_context_for_report已调用 +2026-03-01 15:51:31,028 - Agent - INFO - middleware.py:18 - [tool monitor]执行工具:fetch_external_data +2026-03-01 15:51:31,029 - Agent - INFO - middleware.py:19 - [tool monitor]传入参数:{'user_id': '1005', 'month': '2025-08'} +2026-03-01 15:51:31,031 - Agent - INFO - middleware.py:23 - [tool minitor]工具fetch_external_data调用成功 +2026-03-01 15:51:32,322 - Agent - INFO - middleware.py:39 - [log_before_model]即将调用模型,带有9条消息 +2026-03-01 15:51:32,323 - Agent - DEBUG - middleware.py:40 - [log_before_model]ToolMessage | 消息内容:{"特征": "120㎡ | 老人 | 防滑砖", "效率": "手动操作占比:97%\\n定时清扫未使用", "耗材": "电池衰减:27%\\n水箱未激活", "对比": "语音控制功能需调试+重新教学"} +2026-03-01 15:51:35,470 - Agent - INFO - middleware.py:18 - [tool monitor]执行工具:rag_summarize +2026-03-01 15:51:35,471 - Agent - INFO - middleware.py:19 - [tool monitor]传入参数:{'query': '扫地机器人电池保养和维护建议'} +2026-03-01 15:51:35,896 - Agent - INFO - rag_service.py:33 - [rag_summarize]: 召回了3条参考资料 +2026-03-01 15:51:39,444 - Agent - INFO - middleware.py:23 - [tool minitor]工具rag_summarize调用成功 +2026-03-01 15:51:40,927 - Agent - INFO - middleware.py:39 - [log_before_model]即将调用模型,带有11条消息 +2026-03-01 15:51:40,928 - Agent - DEBUG - middleware.py:40 - [log_before_model]ToolMessage | 消息内容:扫地机器人电池保养和维护建议包括:日常使用后将清扫模式调至“待机”以减少电量消耗;避免自行拆解机器人内部零件(如电池),故障时应联系官方售后;每月进行一次全面功能测试,确保回充等功能正常;每周检查充电座电源适配器是否发热或异响,防止超负荷工作。 +2026-03-01 15:51:50,101 - Agent - INFO - middleware.py:39 - [log_before_model]即将调用模型,带有1条消息 +2026-03-01 15:51:50,105 - Agent - DEBUG - middleware.py:40 - [log_before_model]HumanMessage | 消息内容:生成使用报告 +2026-03-01 15:51:55,052 - Agent - INFO - middleware.py:18 - [tool monitor]执行工具:get_user_id +2026-03-01 15:51:55,053 - Agent - INFO - middleware.py:19 - [tool monitor]传入参数:{} +2026-03-01 15:51:55,054 - Agent - INFO - middleware.py:23 - [tool minitor]工具get_user_id调用成功 +2026-03-01 15:51:55,323 - Agent - INFO - middleware.py:39 - [log_before_model]即将调用模型,带有3条消息 +2026-03-01 15:51:55,323 - Agent - DEBUG - middleware.py:40 - [log_before_model]ToolMessage | 消息内容:1002 +2026-03-01 15:52:01,856 - Agent - INFO - middleware.py:18 - [tool monitor]执行工具:get_current_month +2026-03-01 15:52:01,859 - Agent - INFO - middleware.py:19 - [tool monitor]传入参数:{} +2026-03-01 15:52:01,860 - Agent - INFO - middleware.py:23 - [tool minitor]工具get_current_month调用成功 +2026-03-01 15:52:02,290 - Agent - INFO - middleware.py:39 - [log_before_model]即将调用模型,带有5条消息 +2026-03-01 15:52:02,290 - Agent - DEBUG - middleware.py:40 - [log_before_model]ToolMessage | 消息内容:2025-07 +2026-03-01 15:52:10,291 - Agent - INFO - middleware.py:18 - [tool monitor]执行工具:fill_context_for_report +2026-03-01 15:52:10,294 - Agent - INFO - middleware.py:19 - [tool monitor]传入参数:{} +2026-03-01 15:52:10,296 - Agent - INFO - middleware.py:23 - [tool minitor]工具fill_context_for_report调用成功 +2026-03-01 15:52:11,742 - Agent - INFO - middleware.py:39 - [log_before_model]即将调用模型,带有7条消息 +2026-03-01 15:52:11,742 - Agent - DEBUG - middleware.py:40 - [log_before_model]ToolMessage | 消息内容:fill_context_for_report已调用 +2026-03-01 15:52:16,550 - Agent - INFO - middleware.py:18 - [tool monitor]执行工具:fetch_external_data +2026-03-01 15:52:16,550 - Agent - INFO - middleware.py:19 - [tool monitor]传入参数:{'user_id': '1002', 'month': '2025-07'} +2026-03-01 15:52:16,552 - Agent - INFO - middleware.py:23 - [tool minitor]工具fetch_external_data调用成功 +2026-03-01 15:52:22,752 - Agent - INFO - middleware.py:39 - [log_before_model]即将调用模型,带有9条消息 +2026-03-01 15:52:22,752 - Agent - DEBUG - middleware.py:40 - [log_before_model]ToolMessage | 消息内容:{"特征": "70㎡公寓 | 情侣 | 瓷砖", "效率": "覆盖率:87%\\n避障失败:3次/周(电线+拖鞋)", "耗材": "边刷磨损:中度+\\n尘盒清理:每2天", "对比": "拖地功能使用率低于同类33%"} +2026-03-01 15:52:28,362 - Agent - INFO - middleware.py:18 - [tool monitor]执行工具:rag_summarize +2026-03-01 15:52:28,363 - Agent - INFO - middleware.py:19 - [tool monitor]传入参数:{'query': '扫地机器人边刷磨损维护和更换周期'} +2026-03-01 15:52:28,980 - Agent - INFO - rag_service.py:33 - [rag_summarize]: 召回了3条参考资料 +2026-03-01 15:52:34,082 - Agent - INFO - middleware.py:23 - [tool minitor]工具rag_summarize调用成功 +2026-03-01 15:52:39,482 - Agent - INFO - middleware.py:39 - [log_before_model]即将调用模型,带有11条消息 +2026-03-01 15:52:39,483 - Agent - DEBUG - middleware.py:40 - [log_before_model]ToolMessage | 消息内容:边刷磨损至刷毛长度小于1cm时应立即更换,以避免影响边角清扫效果;磨损会导致边角清扫不彻底,更换时只需拆卸机身底部边刷卡扣,安装新边刷并按压卡紧即可。在宠物家庭等特殊使用环境下,耗材更换周期需缩短。 +2026-03-01 15:52:45,187 - Agent - INFO - middleware.py:18 - [tool monitor]执行工具:rag_summarize +2026-03-01 15:52:45,187 - Agent - INFO - middleware.py:19 - [tool monitor]传入参数:{'query': '扫地机器人避障失败常见原因和解决方案'} +2026-03-01 15:52:45,595 - Agent - INFO - rag_service.py:33 - [rag_summarize]: 召回了3条参考资料 +2026-03-01 15:52:48,668 - Agent - INFO - middleware.py:23 - [tool minitor]工具rag_summarize调用成功 +2026-03-01 15:52:54,679 - Agent - INFO - middleware.py:39 - [log_before_model]即将调用模型,带有13条消息 +2026-03-01 15:52:54,679 - Agent - DEBUG - middleware.py:40 - [log_before_model]ToolMessage | 消息内容:扫地机器人避障失败的常见原因包括避障摄像头或传感器被灰尘、水渍遮挡,防撞条卡顿,以及未开启高级避障模式。解决方案为:用干布擦拭避障组件,轻按防撞条确认回弹正常,清理周围障碍物,并在APP中开启“高级避障模式”后重新建图。 +2026-03-01 15:52:58,313 - Agent - INFO - middleware.py:18 - [tool monitor]执行工具:rag_summarize +2026-03-01 15:52:58,314 - Agent - INFO - middleware.py:19 - [tool monitor]传入参数:{'query': '扫地机器人拖地功能使用频率和技巧'} +2026-03-01 15:52:58,705 - Agent - INFO - rag_service.py:33 - [rag_summarize]: 召回了3条参考资料 +2026-03-01 15:53:04,329 - Agent - INFO - middleware.py:23 - [tool minitor]工具rag_summarize调用成功 +2026-03-01 15:53:13,569 - Agent - INFO - middleware.py:39 - [log_before_model]即将调用模型,带有15条消息 +2026-03-01 15:53:13,572 - Agent - DEBUG - middleware.py:40 - [log_before_model]ToolMessage | 消息内容:拖地功能使用频率和技巧因环境而异:北方干燥多灰环境建议每日扫地、拖地时调至中档出水量;厨房重油污区域拖地后需立即清洗拖布和水箱,每周除垢;卫生间仅扫地不拖地,避免接触积水;水泥地或老旧地砖应减少拖地频次以防灰尘结块;宠物家庭每次使用后需全面清理拖布等部件,耗材更换周期缩短50%;床底、沙发底等区域可在APP中设置“深度拖扫”以增强效果。 diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..bb6482c --- /dev/null +++ b/requirements.txt @@ -0,0 +1,36 @@ +# LangChain + RAG + Agent 智能客服系统依赖 + +# LangChain 核心包 +langchain>=0.3.0 +langchain-core>=0.3.0 +langchain-community>=0.3.0 +langchain-chroma>=0.1.0 +langchain-text-splitters>=0.3.0 +langgraph>=0.2.0 + +# Web 框架 +streamlit + +# 配置管理 +pyyaml +python-dotenv + +# 数据处理 +pandas + +# 向量数据库 +chromadb + +# 文档处理 +pypdf + +# 阿里云服务 +dashscope + +# 其他工具 +requests + +# 开发工具 +black +flake8 +pytest