# AI Agent - 个人生活助手和数据分析助手 ## 项目概述 这是一个基于 LangGraph、LangChain 和 FastAPI 构建的 AI 助手系统,能够处理天气查询、文件读取、网页抓取等任务。采用前后端分离架构,支持 PostgreSQL 持久化对话记忆。 ## 项目结构 ``` Agent1/ ├── tools.py # 工具定义(纯函数、@tool) ├── graph_builder.py # LangGraph 状态图构建(状态定义、节点、边) ├── agent.py # AIAgentService 类(模型初始化、graph 管理、消息处理) ├── backend.py # FastAPI 应用(路由、WebSocket、lifespan) ├── frontend.py # Streamlit 前端(通过 HTTP 调用后端) ├── .env # 环境变量(ZHIPUAI_API_KEY 等) ├── requirement.txt # Python 依赖包列表 └── user_docs/ # 允许读取的文档目录 ├── a.txt ├── b.pdf └── c.xlsx ``` ## 核心功能 - 🌤️ **天气查询**:获取指定地点的当前温度 - 📄 **文本文件读取**:读取 `.txt`、`.md` 等文本文件 - 📑 **PDF 文件读取**:解析 PDF 文件并提取文本内容 - 📊 **Excel 数据处理**:读取 Excel 文件并转换为 Markdown 表格 - 🌐 **网页抓取**:抓取网页正文内容 - 💾 **持久化记忆**:使用 PostgreSQL 保存对话历史,支持多轮对话上下文 - 🔄 **多模型动态切换**:前端可选择不同的大语言模型,后端自动切换处理 ## 技术栈 - **后端框架**:FastAPI + Uvicorn - **前端框架**:Streamlit - **AI 框架**:LangGraph + LangChain - **数据库**:PostgreSQL(用于持久化对话记忆) - **LLM 支持**: - 智谱 AI(glm-4.7-flash):在线服务,响应速度快 - 本地 vLLM(gemma-4-E2B-it):本地部署,数据隐私性好 系统支持多种大语言模型,可在前端动态切换。每个模型在启动时都会预编译独立的 LangGraph,确保最佳性能。如果某个模型初始化失败(如 API Key 未配置),系统会自动降级到可用模型。 ## 环境要求 - Python 3.10+ - PostgreSQL 16+ - Docker(可选,用于运行 PostgreSQL) ## 安装步骤 ### 1. 启动 PostgreSQL 容器 ```bash docker run -d \ --name postgres-langgraph \ -e POSTGRES_PASSWORD=mysecretpassword \ -e POSTGRES_DB=langgraph_db \ -p 5432:5432 \ -v ~/docker_volumes/postgres_data:/var/lib/postgresql/data \ postgres:16 ``` ### 2. 安装 Python 依赖 ```bash pip install fastapi uvicorn streamlit requests psycopg[binary,pool] \ langgraph langgraph-checkpoint-postgres langchain langchain-community \ langchain-openai python-dotenv pypdf pandas beautifulsoup4 ``` 或者使用 requirements.txt: ```bash pip install -r requirement.txt ``` ### 3. 配置环境变量 编辑 `.env` 文件,设置您的 API 密钥: ```env ZHIPUAI_API_KEY=your_zhipuai_api_key_here VLLM_LOCAL_KEY=token-abc123 # 如果使用本地模型 ``` ## 运行步骤 ### 1. 启动后端服务 ```bash python backend.py ``` 看到 `Uvicorn running on http://0.0.0.0:8001` 即表示启动成功。 ### 2. 启动前端界面(新终端) ```bash streamlit run frontend.py ``` 浏览器会自动打开 `http://localhost:8501`,即可开始使用。 ## API 接口 ### POST /chat 同步对话接口,支持模型选择 **请求体:** ```json { "message": "今天北京天气怎么样?", "thread_id": "optional-thread-id", "model": "zhipu" // 可选: "zhipu" 或 "local" } ``` **响应:** ```json { "reply": "当前北京的温度为25℃", "thread_id": "generated-or-provided-thread-id", "model_used": "zhipu" // 实际使用的模型 } ``` **模型选项:** - `zhipu`:智谱 GLM-4.7-Flash(在线) - `local`:本地 vLLM Gemma-4(需要启动 vLLM 容器) ### WebSocket /ws 流式对话接口(可选扩展) ## 使用说明 ### 工具调用示例 1. **查询天气**: ``` 用户:今天上海天气怎么样? ``` 2. **读取文本文件**: ``` 用户:请读取 a.txt 文件的内容 ``` 3. **读取 PDF 文件**: ``` 用户:帮我总结一下 b.pdf 的内容 ``` 4. **读取 Excel 文件**: ``` 用户:显示 c.xlsx 的数据 ``` 5. **抓取网页**: ``` 用户:请抓取 https://example.com 的内容 ``` ### 会话记忆 - 系统会自动为每个会话生成唯一的 `thread_id` - 相同 `thread_id` 的对话会共享历史记录 - 即使重启后端服务,对话历史依然保存在 PostgreSQL 中 - 如需固定会话 ID,可在前端代码中修改 `st.session_state.thread_id` 为固定字符串 ### 多模型切换 **前端操作:** 1. 在左侧边栏的"选择大模型"下拉框中选择模型 2. 可随时切换模型,甚至在同一会话中 3. 点击"🔄 新会话"按钮可清空当前对话并开始新的会话 **后端行为:** - 启动时会预编译所有可用模型的 LangGraph - 如果某个模型初始化失败(如 API Key 未配置),会自动跳过 - 请求时如果选择的模型不可用,会自动降级到第一个可用模型 - 响应中会返回 `model_used` 字段,显示实际使用的模型 **添加新模型:** 在 `agent.py` 的 `initialize()` 方法中的 `model_configs` 字典添加新模型即可: ```python model_configs = { "zhipu": self._create_zhipu_llm, "local": self._create_local_llm, "new_model": self._create_new_model_llm, # 添加新模型 } ``` ## 架构说明 ### 模块职责 - **tools.py**:独立工具模块,包含所有 `@tool` 装饰的纯函数,无外部依赖,可单独测试 - **graph_builder.py**:LangGraph 状态图构建器,定义状态、节点函数和条件边 - **agent.py**:AIAgentService 服务类,负责模型初始化和 graph 编译,使用 `AsyncPostgresSaver` - **backend.py**:FastAPI 应用,提供 REST API 和 WebSocket 接口,端口 8001 - **frontend.py**:Streamlit 前端,通过 HTTP 调用后端 API,实现友好的用户界面 ### 数据流 ``` 用户输入 → Streamlit 前端 → FastAPI 后端 → AIAgentService → LangGraph StateGraph → LLM + Tools → PostgreSQL (记忆) → 返回响应 → 前端展示 ``` ## 注意事项 1. **文件安全**:所有文件读取操作仅限于 `./user_docs` 目录,防止路径遍历攻击 2. **端口冲突**:后端使用 8001 端口,避免与本地 vLLM 服务的 8000 端口冲突 3. **API 密钥**:请妥善保管 `.env` 文件中的 API 密钥,不要提交到版本控制系统 4. **数据库持久化**:PostgreSQL 数据卷挂载到 `~/docker_volumes/postgres_data`,确保数据安全 ## 故障排除 ### 问题:无法连接 PostgreSQL **解决方案:** ```bash # 检查容器是否运行 docker ps | grep postgres-langgraph # 查看容器日志 docker logs postgres-langgraph # 重新启动容器 docker restart postgres-langgraph ``` ### 问题:后端启动失败 **解决方案:** - 确认端口 8001 未被占用 - 检查 `.env` 文件中的 API 密钥是否正确配置 - 确认所有依赖包已正确安装 - 查看启动日志,确认至少有一个模型初始化成功 ### 问题:模型切换后无响应 **解决方案:** - 检查所选模型的配置是否正确(如智谱 API Key) - 确认 vLLM 容器是否正在运行(如果使用本地模型) - 查看后端日志,确认模型是否初始化成功 - 尝试切换到另一个模型 ### 问题:工具调用失败 **解决方案:** - 确认文件位于 `./user_docs` 目录下 - 检查文件格式是否正确 - 查看后端日志获取详细错误信息 ## 许可证 本项目采用 MIT 许可证。详见 [LICENSE](LICENSE) 文件。 ## 贡献 欢迎提交 Issue 和 Pull Request!