7.7 KiB
7.7 KiB
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 容器
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 依赖
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:
pip install -r requirement.txt
3. 配置环境变量
编辑 .env 文件,设置您的 API 密钥:
ZHIPUAI_API_KEY=your_zhipuai_api_key_here
VLLM_LOCAL_KEY=token-abc123 # 如果使用本地模型
运行步骤
1. 启动后端服务
python backend.py
看到 Uvicorn running on http://0.0.0.0:8001 即表示启动成功。
2. 启动前端界面(新终端)
streamlit run frontend.py
浏览器会自动打开 http://localhost:8501,即可开始使用。
API 接口
POST /chat
同步对话接口,支持模型选择
请求体:
{
"message": "今天北京天气怎么样?",
"thread_id": "optional-thread-id",
"model": "zhipu" // 可选: "zhipu" 或 "local"
}
响应:
{
"reply": "当前北京的温度为25℃",
"thread_id": "generated-or-provided-thread-id",
"model_used": "zhipu" // 实际使用的模型
}
模型选项:
zhipu:智谱 GLM-4.7-Flash(在线)local:本地 vLLM Gemma-4(需要启动 vLLM 容器)
WebSocket /ws
流式对话接口(可选扩展)
使用说明
工具调用示例
-
查询天气:
用户:今天上海天气怎么样? -
读取文本文件:
用户:请读取 a.txt 文件的内容 -
读取 PDF 文件:
用户:帮我总结一下 b.pdf 的内容 -
读取 Excel 文件:
用户:显示 c.xlsx 的数据 -
抓取网页:
用户:请抓取 https://example.com 的内容
会话记忆
- 系统会自动为每个会话生成唯一的
thread_id - 相同
thread_id的对话会共享历史记录 - 即使重启后端服务,对话历史依然保存在 PostgreSQL 中
- 如需固定会话 ID,可在前端代码中修改
st.session_state.thread_id为固定字符串
多模型切换
前端操作:
- 在左侧边栏的"选择大模型"下拉框中选择模型
- 可随时切换模型,甚至在同一会话中
- 点击"🔄 新会话"按钮可清空当前对话并开始新的会话
后端行为:
- 启动时会预编译所有可用模型的 LangGraph
- 如果某个模型初始化失败(如 API Key 未配置),会自动跳过
- 请求时如果选择的模型不可用,会自动降级到第一个可用模型
- 响应中会返回
model_used字段,显示实际使用的模型
添加新模型:
在 agent.py 的 initialize() 方法中的 model_configs 字典添加新模型即可:
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 (记忆)
→ 返回响应 → 前端展示
注意事项
- 文件安全:所有文件读取操作仅限于
./user_docs目录,防止路径遍历攻击 - 端口冲突:后端使用 8001 端口,避免与本地 vLLM 服务的 8000 端口冲突
- API 密钥:请妥善保管
.env文件中的 API 密钥,不要提交到版本控制系统 - 数据库持久化:PostgreSQL 数据卷挂载到
~/docker_volumes/postgres_data,确保数据安全
故障排除
问题:无法连接 PostgreSQL
解决方案:
# 检查容器是否运行
docker ps | grep postgres-langgraph
# 查看容器日志
docker logs postgres-langgraph
# 重新启动容器
docker restart postgres-langgraph
问题:后端启动失败
解决方案:
- 确认端口 8001 未被占用
- 检查
.env文件中的 API 密钥是否正确配置 - 确认所有依赖包已正确安装
- 查看启动日志,确认至少有一个模型初始化成功
问题:模型切换后无响应
解决方案:
- 检查所选模型的配置是否正确(如智谱 API Key)
- 确认 vLLM 容器是否正在运行(如果使用本地模型)
- 查看后端日志,确认模型是否初始化成功
- 尝试切换到另一个模型
问题:工具调用失败
解决方案:
- 确认文件位于
./user_docs目录下 - 检查文件格式是否正确
- 查看后端日志获取详细错误信息
许可证
本项目采用 MIT 许可证。详见 LICENSE 文件。
贡献
欢迎提交 Issue 和 Pull Request!