docs(.gitignore/README/QUICKSTART): 更新文档和忽略配置 - 添加IDE配置、日志和数据文件到.gitignore - 重构QUICKSTART.md,提供Docker Compose和本地开发两种部署方式 - 更新README.md,优化项目介绍和架构说明 - 移除旧的agent.py和backend.py文件 ```
This commit is contained in:
9
.env.example
Normal file
9
.env.example
Normal file
@@ -0,0 +1,9 @@
|
||||
# AI Agent 环境变量配置模板
|
||||
# 复制此文件为 .env 并填入真实的 API Key
|
||||
LOCAL_MODEL_PATH=gemma-4-E2B-it
|
||||
# 智谱 AI API Key(必需)
|
||||
# 获取地址: https://open.bigmodel.cn/
|
||||
ZHIPUAI_API_KEY=4d568a4367f1442bbc226cc0daf84566.44SsKVWkVIM2Mkeg
|
||||
|
||||
# vLLM 本地模型 Token(可选,仅使用本地模型时需要)
|
||||
VLLM_LOCAL_KEY=token-abc123
|
||||
61
.gitea/workflows/deploy.yml
Normal file
61
.gitea/workflows/deploy.yml
Normal file
@@ -0,0 +1,61 @@
|
||||
name: 构建并部署 AI Agent 服务
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main, master ]
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: 检出代码
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: 设置 Python 3.11
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: '3.11'
|
||||
|
||||
- name: 缓存 pip 依赖
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/.cache/pip
|
||||
key: ${{ runner.os }}-pip-${{ hashFiles('requirement.txt') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-pip-
|
||||
|
||||
- name: 安装 Python 依赖 (仅用于验证)
|
||||
run: pip install -r requirement.txt
|
||||
|
||||
- name: 准备环境变量文件
|
||||
run: |
|
||||
cat > .env << EOF
|
||||
ZHIPUAI_API_KEY=${{ secrets.ZHIPUAI_API_KEY }}
|
||||
VLLM_LOCAL_KEY=${{ secrets.VLLM_LOCAL_KEY }}
|
||||
EOF
|
||||
|
||||
- name: 重新构建并启动前后端服务(不影响数据库)
|
||||
run: docker compose up -d --build backend frontend
|
||||
|
||||
- name: 健康检查
|
||||
run: |
|
||||
echo "等待后端服务启动..."
|
||||
sleep 15
|
||||
for i in {1..10}; do
|
||||
if curl -f http://localhost:8001/ > /dev/null 2>&1; then
|
||||
echo "✅ 后端服务正常"
|
||||
exit 0
|
||||
fi
|
||||
echo "等待中... ($i/10)"
|
||||
sleep 5
|
||||
done
|
||||
echo "❌ 后端服务未就绪,查看日志:"
|
||||
docker compose logs backend --tail 50
|
||||
exit 1
|
||||
|
||||
- name: 清理无用的 Docker 资源
|
||||
run: docker system prune -f
|
||||
|
||||
- name: 显示运行状态
|
||||
run: docker compose ps
|
||||
13
.gitignore
vendored
13
.gitignore
vendored
@@ -137,6 +137,19 @@ ENV/
|
||||
env.bak/
|
||||
venv.bak/
|
||||
|
||||
# IDE 配置
|
||||
.vscode/
|
||||
.idea/
|
||||
|
||||
# 日志和数据
|
||||
logs/
|
||||
*.log
|
||||
data/*.db
|
||||
data/*.sqlite
|
||||
|
||||
# Docker 卷数据
|
||||
pg_data/
|
||||
|
||||
# Spyder project settings
|
||||
.spyderproject
|
||||
.spyproject
|
||||
|
||||
434
QUICKSTART.md
434
QUICKSTART.md
@@ -1,38 +1,65 @@
|
||||
# 快速开始指南 - 多模型切换功能
|
||||
# 快速开始指南
|
||||
|
||||
## 🚀 5分钟快速启动
|
||||
详细的启动和部署指南,面向开发者和运维人员。
|
||||
|
||||
### 步骤 1: 启动必要的容器
|
||||
---
|
||||
|
||||
## 🚀 快速启动(3 步)
|
||||
|
||||
### 方式一:Docker Compose(推荐 ⭐)
|
||||
|
||||
适合生产环境,一键启动所有服务。
|
||||
|
||||
#### 1. 配置环境变量
|
||||
|
||||
```bash
|
||||
# 使用提供的启动脚本(推荐)
|
||||
./start.sh
|
||||
cat > .env << EOF
|
||||
ZHIPUAI_API_KEY=your_zhipuai_api_key_here
|
||||
VLLM_LOCAL_KEY=token-abc123
|
||||
EOF
|
||||
```
|
||||
|
||||
# 或者手动启动容器
|
||||
# 1. 启动 vLLM (如果需要本地模型)
|
||||
docker run -d --rm \
|
||||
--group-add=video \
|
||||
--cap-add=SYS_PTRACE \
|
||||
--security-opt seccomp=unconfined \
|
||||
--device=/dev/kfd \
|
||||
--device=/dev/dri \
|
||||
-v /home/huang/Study/AIModel/gemma-4-E2B-it:/models/gemma-4-E2B-it \
|
||||
-e VLLM_ROCM_USE_AITER=0 \
|
||||
-e HF_TOKEN="$HF_TOKEN" \
|
||||
-p 8000:8000 \
|
||||
--ipc=host \
|
||||
--entrypoint vllm \
|
||||
my-vllm-gemma4:working \
|
||||
serve /models/gemma-4-E2B-it \
|
||||
--served-model-name gemma-4-E2B-it \
|
||||
--dtype auto \
|
||||
--api-key token-abc123 \
|
||||
--trust-remote-code \
|
||||
--port 8000 \
|
||||
--gpu-memory-utilization 0.85 \
|
||||
--max-model-len 8192
|
||||
#### 2. 启动服务
|
||||
|
||||
# 2. 启动 PostgreSQL
|
||||
```bash
|
||||
docker compose up -d --build
|
||||
```
|
||||
|
||||
#### 3. 访问应用
|
||||
|
||||
- **前端**: http://localhost:8501
|
||||
- **后端 API**: http://localhost:8001
|
||||
|
||||
#### 常用命令
|
||||
|
||||
```bash
|
||||
# 查看服务状态
|
||||
docker compose ps
|
||||
|
||||
# 查看日志
|
||||
docker compose logs -f
|
||||
|
||||
# 重启特定服务
|
||||
docker compose restart backend
|
||||
|
||||
# 停止所有服务
|
||||
docker compose down
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 方式二:本地开发模式
|
||||
|
||||
适合开发和调试。
|
||||
|
||||
#### 前置要求
|
||||
|
||||
- Python 3.10+
|
||||
- Docker(用于 PostgreSQL)
|
||||
|
||||
#### 1. 启动 PostgreSQL
|
||||
|
||||
```bash
|
||||
docker run -d \
|
||||
--name postgres-langgraph \
|
||||
-e POSTGRES_PASSWORD=mysecretpassword \
|
||||
@@ -42,109 +69,126 @@ docker run -d \
|
||||
postgres:16
|
||||
```
|
||||
|
||||
### 步骤 2: 配置环境变量
|
||||
#### 2. 安装依赖
|
||||
|
||||
```bash
|
||||
pip install -r requirement.txt
|
||||
```
|
||||
|
||||
#### 3. 配置环境变量
|
||||
|
||||
编辑 `.env` 文件:
|
||||
|
||||
```env
|
||||
ZHIPUAI_API_KEY=your_actual_zhipuai_api_key
|
||||
VLLM_LOCAL_KEY=token-abc123
|
||||
ZHIPUAI_API_KEY=your_api_key_here
|
||||
```
|
||||
|
||||
### 步骤 3: 启动服务
|
||||
#### 4. 启动服务
|
||||
|
||||
**终端 1 - 后端:**
|
||||
```bash
|
||||
# 方式1: 使用启动脚本(推荐)
|
||||
./start.sh
|
||||
|
||||
# 方式2: 手动启动
|
||||
# 终端1: 启动后端
|
||||
python backend.py
|
||||
```
|
||||
|
||||
# 终端2: 启动前端
|
||||
**终端 2 - 前端:**
|
||||
```bash
|
||||
streamlit run frontend.py
|
||||
```
|
||||
|
||||
### 步骤 4: 访问应用
|
||||
|
||||
浏览器打开: `http://localhost:8501`
|
||||
浏览器自动打开 http://localhost:8501
|
||||
|
||||
---
|
||||
|
||||
## 🎯 使用多模型切换功能
|
||||
## 🐳 Docker 部署详解
|
||||
|
||||
### 在前端切换模型
|
||||
### 文件说明
|
||||
|
||||
1. **打开侧边栏**:点击左上角的菜单图标
|
||||
2. **选择模型**:在"选择大模型"下拉框中选择:
|
||||
- 智谱 GLM-4.7-Flash(在线)
|
||||
- 本地 vLLM(Gemma-4)
|
||||
3. **开始对话**:输入您的问题,系统会使用选定的模型处理
|
||||
| 文件 | 用途 |
|
||||
|------|------|
|
||||
| `docker-compose.yml` | 服务编排配置 |
|
||||
| `Dockerfile.backend` | 后端镜像构建 |
|
||||
| `Dockerfile.frontend` | 前端镜像构建 |
|
||||
| `.gitea/workflows/deploy.yml` | CI/CD 自动化部署 |
|
||||
|
||||
### 特性说明
|
||||
### docker-compose.yml 结构
|
||||
|
||||
✅ **实时切换**:可以在对话过程中随时切换模型
|
||||
✅ **记忆共享**:同一会话 ID 下,不同模型共享对话历史
|
||||
✅ **自动降级**:如果选择的模型不可用,自动切换到可用模型
|
||||
✅ **状态显示**:每条回复下方会显示实际使用的模型
|
||||
|
||||
---
|
||||
|
||||
## 🧪 测试功能
|
||||
|
||||
### 运行自动化测试
|
||||
|
||||
```bash
|
||||
# 确保后端正在运行
|
||||
python test_multi_model.py
|
||||
```yaml
|
||||
services:
|
||||
postgres: # PostgreSQL 数据库
|
||||
backend: # FastAPI 后端服务
|
||||
frontend: # Streamlit 前端界面
|
||||
```
|
||||
|
||||
测试内容包括:
|
||||
- 各模型的可用性测试
|
||||
- 跨模型会话记忆测试
|
||||
- API 响应格式验证
|
||||
**特性:**
|
||||
- ✅ PostgreSQL 健康检查,确保数据库就绪后才启动后端
|
||||
- ✅ 数据持久化到 Docker volume
|
||||
- ✅ 自动重启策略(`restart: unless-stopped`)
|
||||
- ✅ 内部网络隔离,外部无法直接访问数据库
|
||||
|
||||
### 手动测试
|
||||
### 只更新特定服务
|
||||
|
||||
1. **测试智谱模型**:
|
||||
- 选择"智谱 GLM-4.7-Flash"
|
||||
- 询问:"你好,请介绍一下自己"
|
||||
- 观察回复速度和内容质量
|
||||
```bash
|
||||
# 只重新构建后端(不影响数据库)
|
||||
docker compose up -d --build backend
|
||||
|
||||
2. **测试本地模型**:
|
||||
- 选择"本地 vLLM(Gemma-4)"
|
||||
- 询问相同问题
|
||||
- 对比两个模型的回复差异
|
||||
# 只重新启动前端
|
||||
docker compose up -d frontend
|
||||
```
|
||||
|
||||
3. **测试记忆功能**:
|
||||
- 第一轮(智谱模型):"我叫小明,记住我的名字"
|
||||
- 第二轮(本地模型):"我叫什么名字?"
|
||||
- 验证是否能正确回忆
|
||||
### 数据持久化
|
||||
|
||||
PostgreSQL 数据存储在命名 volume `pg_data` 中:
|
||||
|
||||
```bash
|
||||
# 查看 volume
|
||||
docker volume ls | grep pg_data
|
||||
|
||||
# 备份数据
|
||||
docker run --rm -v pg_data:/data -v $(pwd):/backup alpine tar czf /backup/pg_backup.tar.gz /data
|
||||
|
||||
# 恢复数据
|
||||
docker run --rm -v pg_data:/data -v $(pwd):/backup alpine tar xzf /backup/pg_backup.tar.gz -C /
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔧 常见问题
|
||||
## 🔧 开发指南
|
||||
|
||||
### Q1: 某个模型初始化失败怎么办?
|
||||
### 添加新工具
|
||||
|
||||
**A:** 系统会自动跳过失败的模型,使用其他可用模型。检查日志了解具体原因:
|
||||
- 智谱模型:确认 `ZHIPUAI_API_KEY` 是否正确
|
||||
- 本地模型:确认 vLLM 容器是否运行
|
||||
在 `tools.py` 中添加:
|
||||
|
||||
### Q2: 如何添加新模型?
|
||||
```python
|
||||
@tool
|
||||
def my_new_tool(param: str) -> str:
|
||||
"""
|
||||
工具描述(会显示给 LLM)
|
||||
|
||||
**A:** 在 `agent.py` 中添加:
|
||||
Args:
|
||||
param: 参数说明
|
||||
|
||||
Returns:
|
||||
返回值说明
|
||||
"""
|
||||
# 实现逻辑
|
||||
return result
|
||||
```
|
||||
|
||||
工具会自动注册,无需修改其他文件。
|
||||
|
||||
### 添加新模型
|
||||
|
||||
在 `agent.py` 中:
|
||||
|
||||
```python
|
||||
def _create_new_model_llm(self):
|
||||
"""创建新模型的 LLM"""
|
||||
return YourChatModel(
|
||||
model="model-name",
|
||||
api_key="your-key",
|
||||
# ... 其他参数
|
||||
api_key=os.getenv("YOUR_API_KEY"),
|
||||
)
|
||||
|
||||
# 在 initialize() 方法的 model_configs 中添加
|
||||
# 在 initialize() 方法中注册
|
||||
model_configs = {
|
||||
"zhipu": self._create_zhipu_llm,
|
||||
"local": self._create_local_llm,
|
||||
@@ -152,94 +196,190 @@ model_configs = {
|
||||
}
|
||||
```
|
||||
|
||||
然后在前端 `frontend.py` 的 `MODEL_OPTIONS` 中添加对应选项。
|
||||
在前端 `frontend.py` 中添加选项:
|
||||
|
||||
### Q3: 会话记忆是如何工作的?
|
||||
```python
|
||||
MODEL_OPTIONS = {
|
||||
"智谱 GLM-4": "zhipu",
|
||||
"本地 Gemma-4": "local",
|
||||
"新模型": "new_model", # 新增
|
||||
}
|
||||
```
|
||||
|
||||
**A:**
|
||||
- 使用 PostgreSQL 存储对话历史
|
||||
- 通过 `thread_id` 关联同一会话的消息
|
||||
- 不同模型共享同一个 checkpointer,因此可以跨模型保持上下文
|
||||
- 点击"新会话"按钮会生成新的 `thread_id`
|
||||
### 调试技巧
|
||||
|
||||
### Q4: 性能优化建议
|
||||
```bash
|
||||
# 进入后端容器
|
||||
docker compose exec backend bash
|
||||
|
||||
**A:**
|
||||
- 智谱模型:适合快速响应场景,无需本地 GPU
|
||||
- 本地模型:适合数据隐私要求高的场景,需要 GPU 支持
|
||||
- 长时间对话建议定期开启新会话,避免上下文过长
|
||||
# 查看实时日志
|
||||
docker compose logs -f backend
|
||||
|
||||
# 检查数据库连接
|
||||
docker compose exec postgres psql -U postgres -d langgraph_db -c "\dt"
|
||||
|
||||
# 测试后端 API
|
||||
curl http://localhost:8001/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📊 架构优势
|
||||
## 🔄 CI/CD 自动化部署
|
||||
|
||||
### 预编译 Graph
|
||||
### Gitea Workflows
|
||||
|
||||
每个模型在启动时都会预编译独立的 LangGraph:
|
||||
- ✅ 避免每次请求都重新编译,提升性能
|
||||
- ✅ 各模型独立,互不影响
|
||||
- ✅ 支持热插拔,可动态添加/移除模型
|
||||
项目包含自动化部署配置 `.gitea/workflows/deploy.yml`。
|
||||
|
||||
### 智能降级
|
||||
**触发条件:**
|
||||
- 推送到 `main` 或 `master` 分支
|
||||
- 手动触发(workflow_dispatch)
|
||||
|
||||
如果选择的模型不可用:
|
||||
1. 后端自动切换到第一个可用模型
|
||||
2. 返回响应中包含 `model_used` 字段
|
||||
3. 前端显示实际使用的模型
|
||||
4. 用户无感知,体验流畅
|
||||
**部署流程:**
|
||||
1. 检出代码
|
||||
2. 安装 Python 依赖(验证用)
|
||||
3. 准备环境变量
|
||||
4. 重新构建并启动前后端(不影响数据库)
|
||||
5. 健康检查(等待后端就绪)
|
||||
6. 清理无用 Docker 资源
|
||||
|
||||
### 统一接口
|
||||
**配置 Secrets:**
|
||||
|
||||
无论使用哪个模型:
|
||||
- API 接口保持一致
|
||||
- 工具调用方式相同
|
||||
- 会话记忆机制统一
|
||||
- 前端操作体验一致
|
||||
在 Gitea 仓库设置中添加:
|
||||
- `ZHIPUAI_API_KEY`
|
||||
- `VLLM_LOCAL_KEY`
|
||||
|
||||
---
|
||||
|
||||
## 🎓 进阶使用
|
||||
## 🐛 故障排查
|
||||
|
||||
### 固定会话 ID
|
||||
### 常见问题
|
||||
|
||||
如需在不同浏览器或设备间继续同一会话:
|
||||
#### 1. PostgreSQL 连接失败
|
||||
|
||||
```python
|
||||
# 在 frontend.py 中修改
|
||||
st.session_state.thread_id = "my_fixed_session_id"
|
||||
```bash
|
||||
# 检查容器状态
|
||||
docker compose ps postgres
|
||||
|
||||
# 查看日志
|
||||
docker compose logs postgres
|
||||
|
||||
# 测试连接
|
||||
docker compose exec postgres pg_isready -U postgres
|
||||
```
|
||||
|
||||
### 自定义超时时间
|
||||
**解决方案:**
|
||||
- 确认容器正在运行
|
||||
- 检查密码是否正确
|
||||
- 等待健康检查通过(约 10-30 秒)
|
||||
|
||||
```python
|
||||
# 在 frontend.py 中修改 timeout 参数
|
||||
response = requests.post(
|
||||
API_URL,
|
||||
json={...},
|
||||
timeout=120 # 增加到 120 秒
|
||||
)
|
||||
#### 2. 后端启动失败
|
||||
|
||||
```bash
|
||||
# 查看详细日志
|
||||
docker compose logs backend
|
||||
|
||||
# 检查端口占用
|
||||
lsof -i :8001
|
||||
```
|
||||
|
||||
### 批量测试
|
||||
**常见原因:**
|
||||
- API Key 未配置或错误
|
||||
- 端口 8001 被占用
|
||||
- 依赖包缺失
|
||||
|
||||
```python
|
||||
# 创建测试脚本
|
||||
import requests
|
||||
#### 3. 前端无法连接后端
|
||||
|
||||
messages = ["问题1", "问题2", "问题3"]
|
||||
for msg in messages:
|
||||
response = requests.post(API_URL, json={"message": msg, "model": "zhipu"})
|
||||
print(response.json()["reply"])
|
||||
```bash
|
||||
# 检查后端是否正常运行
|
||||
curl http://localhost:8001/
|
||||
|
||||
# 检查网络连接
|
||||
docker compose exec frontend ping backend
|
||||
```
|
||||
|
||||
**解决方案:**
|
||||
- 确认后端服务已启动
|
||||
- 检查防火墙设置
|
||||
- 重启前端服务
|
||||
|
||||
#### 4. 模型初始化失败
|
||||
|
||||
```bash
|
||||
# 查看后端启动日志
|
||||
docker compose logs backend | grep -i "model\|error"
|
||||
```
|
||||
|
||||
**可能原因:**
|
||||
- 智谱 API Key 无效
|
||||
- vLLM 容器未启动(如使用本地模型)
|
||||
- 网络连接问题
|
||||
|
||||
---
|
||||
|
||||
## 📊 监控和维护
|
||||
|
||||
### 查看资源使用
|
||||
|
||||
```bash
|
||||
# Docker 容器资源使用
|
||||
docker stats
|
||||
|
||||
# 磁盘空间
|
||||
docker system df
|
||||
|
||||
# 清理无用资源
|
||||
docker system prune -f
|
||||
```
|
||||
|
||||
### 日志管理
|
||||
|
||||
```bash
|
||||
# 查看所有服务日志
|
||||
docker compose logs
|
||||
|
||||
# 查看特定服务最近 100 行日志
|
||||
docker compose logs --tail=100 backend
|
||||
|
||||
# 实时跟踪日志
|
||||
docker compose logs -f backend frontend
|
||||
```
|
||||
|
||||
### 备份和恢复
|
||||
|
||||
```bash
|
||||
# 备份数据库
|
||||
docker compose exec postgres pg_dump -U postgres langgraph_db > backup.sql
|
||||
|
||||
# 恢复数据库
|
||||
cat backup.sql | docker compose exec -T postgres psql -U postgres langgraph_db
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎯 性能优化建议
|
||||
|
||||
### 开发环境
|
||||
|
||||
- 使用 `docker compose watch` 实现热重载(需配置)
|
||||
- 挂载代码目录而非复制到镜像
|
||||
- 启用 Python 调试模式
|
||||
|
||||
### 生产环境
|
||||
|
||||
- 使用反向代理(Nginx)
|
||||
- 启用 HTTPS
|
||||
- 配置日志轮转
|
||||
- 设置资源限制(CPU、内存)
|
||||
- 定期备份数据库
|
||||
|
||||
---
|
||||
|
||||
## 📞 获取帮助
|
||||
|
||||
- 查看完整文档:[README.md](README.md)
|
||||
- 查看项目结构:参考 [README.md](README.md) 中的项目结构部分
|
||||
- 报告问题:提交 Issue 并附上日志信息
|
||||
- **完整文档**: [README.md](README.md)
|
||||
- **RAG 示例**: `rag_example.py`
|
||||
- **报告问题**: 提交 Issue 并附上日志
|
||||
|
||||
---
|
||||
|
||||
**祝您使用愉快!** 🎉
|
||||
**祝您部署顺利!** 🎉
|
||||
|
||||
402
README.md
402
README.md
@@ -1,192 +1,205 @@
|
||||
# AI Agent - 个人生活助手和数据分析助手
|
||||
# AI Agent - 智能助手系统
|
||||
|
||||
## 项目概述
|
||||
一个基于 LangGraph + FastAPI 的智能对话助手,支持多模型切换、RAG 知识库检索、文件处理和网页抓取等功能。
|
||||
|
||||
这是一个基于 LangGraph、LangChain 和 FastAPI 构建的 AI 助手系统,能够处理天气查询、文件读取、网页抓取等任务。采用前后端分离架构,支持 PostgreSQL 持久化对话记忆。
|
||||
---
|
||||
|
||||
## 项目结构
|
||||
## 🎯 核心功能
|
||||
|
||||
### 面向用户的功能
|
||||
|
||||
- 💬 **智能对话**:支持多轮对话,自动记忆上下文
|
||||
- 🌤️ **天气查询**:实时获取各地天气信息
|
||||
- 📄 **文档处理**:读取 TXT、PDF、Excel 等格式文件
|
||||
- 🌐 **网页抓取**:提取网页正文内容
|
||||
- 🔍 **知识库检索(RAG)**:基于向量数据库的智能问答
|
||||
- 🔄 **多模型切换**:前端可选择不同大语言模型
|
||||
|
||||
### 技术特性
|
||||
|
||||
- ✅ **持久化记忆**:PostgreSQL 存储对话历史,重启不丢失
|
||||
- ✅ **高可用架构**:模型自动降级,确保服务稳定
|
||||
- ✅ **前后端分离**:FastAPI 后端 + Streamlit 前端
|
||||
- ✅ **Docker 部署**:一键启动所有服务
|
||||
|
||||
---
|
||||
|
||||
## 🏗️ 技术架构
|
||||
|
||||
### 技术栈
|
||||
|
||||
| 层级 | 技术选型 | 说明 |
|
||||
|------|---------|------|
|
||||
| **LLM 服务** | 智谱 AI API / vLLM (Gemma-4) | 云端 API 或本地推理 |
|
||||
| **Embedding** | 智谱 Embedding API | 向量嵌入(无需 PyTorch) |
|
||||
| **Agent 框架** | LangGraph + LangChain | 工作流编排 |
|
||||
| **向量数据库** | ChromaDB / pgvector | RAG 知识检索 |
|
||||
| **后端框架** | FastAPI + Uvicorn | RESTful API + WebSocket |
|
||||
| **前端框架** | Streamlit | 交互式 Web 界面 |
|
||||
| **数据库** | PostgreSQL 16 | 对话记忆持久化 |
|
||||
| **容器化** | Docker + Docker Compose | 服务编排 |
|
||||
|
||||
### 架构图
|
||||
|
||||
```
|
||||
┌──────────────┐
|
||||
│ 用户浏览器 │ Streamlit 前端 (8501)
|
||||
└──────┬───────┘
|
||||
│ HTTP/WebSocket
|
||||
↓
|
||||
┌──────────────────┐
|
||||
│ FastAPI 后端 │ 端口 8001
|
||||
│ ┌────────────┐ │
|
||||
│ │ AIAgent │ │ 多模型管理
|
||||
│ └─────┬──────┘ │
|
||||
│ │ │
|
||||
│ ┌─────▼──────┐ │
|
||||
│ │LangGraph │ │ 工作流引擎
|
||||
│ │ StateGraph │ │
|
||||
│ └─────┬──────┘ │
|
||||
│ │ │
|
||||
│ ┌─────▼──────┐ │
|
||||
│ │ Tools │ │ 工具集合
|
||||
│ │ - Weather │ │
|
||||
│ │ - File IO │ │
|
||||
│ │ - Web Scrap│ │
|
||||
│ │ - RAG │ │
|
||||
│ └────────────┘ │
|
||||
└────────┬─────────┘
|
||||
│
|
||||
┌────┴────┐
|
||||
↓ ↓
|
||||
┌────────┐ ┌──────────┐
|
||||
│PostgreSQL│ │ChromaDB │
|
||||
│(记忆存储)│ │(向量检索)│
|
||||
└────────┘ └──────────┘
|
||||
```
|
||||
|
||||
### 项目结构
|
||||
|
||||
```
|
||||
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/ # 允许读取的文档目录
|
||||
├── agent.py # Agent 服务核心(多模型管理)
|
||||
├── graph_builder.py # LangGraph 状态图构建器
|
||||
├── tools.py # 工具函数定义(@tool 装饰器)
|
||||
├── backend.py # FastAPI 后端应用
|
||||
├── frontend.py # Streamlit 前端界面
|
||||
├── rag_example.py # RAG 实现示例(无 PyTorch)
|
||||
├── docker-compose.yml # Docker 服务编排
|
||||
├── Dockerfile.backend # 后端镜像构建
|
||||
├── Dockerfile.frontend # 前端镜像构建
|
||||
├── requirement.txt # Python 依赖
|
||||
├── .env # 环境变量配置
|
||||
└── user_docs/ # 用户文档目录
|
||||
├── a.txt
|
||||
├── b.pdf
|
||||
└── c.xlsx
|
||||
```
|
||||
|
||||
## 核心功能
|
||||
---
|
||||
|
||||
- 🌤️ **天气查询**:获取指定地点的当前温度
|
||||
- 📄 **文本文件读取**:读取 `.txt`、`.md` 等文本文件
|
||||
- 📑 **PDF 文件读取**:解析 PDF 文件并提取文本内容
|
||||
- 📊 **Excel 数据处理**:读取 Excel 文件并转换为 Markdown 表格
|
||||
- 🌐 **网页抓取**:抓取网页正文内容
|
||||
- 💾 **持久化记忆**:使用 PostgreSQL 保存对话历史,支持多轮对话上下文
|
||||
- 🔄 **多模型动态切换**:前端可选择不同的大语言模型,后端自动切换处理
|
||||
## 🚀 快速开始
|
||||
|
||||
## 技术栈
|
||||
详细启动指南请查看 [QUICKSTART.md](QUICKSTART.md)
|
||||
|
||||
- **后端框架**: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 Compose(推荐)
|
||||
|
||||
```bash
|
||||
docker run -d \
|
||||
--name postgres-langgraph \
|
||||
# 1. 配置 .env 文件
|
||||
echo "ZHIPUAI_API_KEY=your_key_here" > .env
|
||||
|
||||
# 2. 启动所有服务
|
||||
docker compose up -d --build
|
||||
|
||||
# 3. 访问应用
|
||||
# 前端: http://localhost:8501
|
||||
# 后端: http://localhost:8001
|
||||
```
|
||||
|
||||
### 方式二:本地开发模式
|
||||
|
||||
```bash
|
||||
# 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
|
||||
```
|
||||
-p 5432:5432 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
|
||||
# 2. 安装依赖
|
||||
pip install -r requirement.txt
|
||||
```
|
||||
|
||||
### 3. 配置环境变量
|
||||
|
||||
编辑 `.env` 文件,设置您的 API 密钥:
|
||||
|
||||
```env
|
||||
ZHIPUAI_API_KEY=your_zhipuai_api_key_here
|
||||
VLLM_LOCAL_KEY=token-abc123 # 如果使用本地模型
|
||||
```
|
||||
|
||||
## 运行步骤
|
||||
|
||||
### 1. 启动后端服务
|
||||
|
||||
```bash
|
||||
# 3. 启动后端
|
||||
python backend.py
|
||||
```
|
||||
|
||||
看到 `Uvicorn running on http://0.0.0.0:8001` 即表示启动成功。
|
||||
|
||||
### 2. 启动前端界面(新终端)
|
||||
|
||||
```bash
|
||||
# 4. 启动前端(新终端)
|
||||
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" // 实际使用的模型
|
||||
}
|
||||
你好,请介绍一下自己
|
||||
今天北京天气怎么样?
|
||||
帮我总结一下 a.txt 的内容
|
||||
```
|
||||
|
||||
**模型选项:**
|
||||
- `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` 为固定字符串
|
||||
| 功能 | 示例提问 |
|
||||
|------|---------|
|
||||
| 🌤️ 天气查询 | "上海今天天气如何?" |
|
||||
| 📄 读取文本 | "读取 a.txt 的内容" |
|
||||
| 📑 解析 PDF | "总结 b.pdf 的主要内容" |
|
||||
| 📊 Excel 数据 | "显示 c.xlsx 的数据" |
|
||||
| 🌐 网页抓取 | "抓取 https://example.com 的内容" |
|
||||
| 🔍 知识库检索 | "根据知识库回答:XXX" |
|
||||
|
||||
### 多模型切换
|
||||
|
||||
**前端操作:**
|
||||
1. 在左侧边栏的"选择大模型"下拉框中选择模型
|
||||
2. 可随时切换模型,甚至在同一会话中
|
||||
3. 点击"🔄 新会话"按钮可清空当前对话并开始新的会话
|
||||
1. 在左侧边栏选择模型:
|
||||
- **智谱 GLM-4**:在线服务,速度快
|
||||
- **本地 Gemma-4**:本地部署,隐私性好
|
||||
|
||||
**后端行为:**
|
||||
- 启动时会预编译所有可用模型的 LangGraph
|
||||
- 如果某个模型初始化失败(如 API Key 未配置),会自动跳过
|
||||
- 请求时如果选择的模型不可用,会自动降级到第一个可用模型
|
||||
- 响应中会返回 `model_used` 字段,显示实际使用的模型
|
||||
2. 可随时切换,甚至在同一会话中
|
||||
|
||||
3. 点击 "🔄 新会话" 清空当前对话
|
||||
|
||||
---
|
||||
|
||||
## 🔧 开发指南
|
||||
|
||||
### 添加新工具
|
||||
|
||||
在 `tools.py` 中添加新的 `@tool` 装饰函数:
|
||||
|
||||
```python
|
||||
@tool
|
||||
def my_new_tool(param: str) -> str:
|
||||
"""
|
||||
工具描述(会显示给 LLM)
|
||||
|
||||
Args:
|
||||
param: 参数说明
|
||||
|
||||
Returns:
|
||||
返回值说明
|
||||
"""
|
||||
# 实现逻辑
|
||||
return result
|
||||
```
|
||||
|
||||
工具会自动注册到 `AVAILABLE_TOOLS` 列表中。
|
||||
|
||||
### 添加新模型
|
||||
|
||||
在 `agent.py` 的 `initialize()` 方法中添加模型配置:
|
||||
|
||||
**添加新模型:**
|
||||
在 `agent.py` 的 `initialize()` 方法中的 `model_configs` 字典添加新模型即可:
|
||||
```python
|
||||
model_configs = {
|
||||
"zhipu": self._create_zhipu_llm,
|
||||
@@ -195,74 +208,75 @@ model_configs = {
|
||||
}
|
||||
```
|
||||
|
||||
## 架构说明
|
||||
### Docker 部署
|
||||
|
||||
### 模块职责
|
||||
项目包含完整的 Docker 配置:
|
||||
|
||||
- **tools.py**:独立工具模块,包含所有 `@tool` 装饰的纯函数,无外部依赖,可单独测试
|
||||
- **graph_builder.py**:LangGraph 状态图构建器,定义状态、节点函数和条件边
|
||||
- **agent.py**:AIAgentService 服务类,负责模型初始化和 graph 编译,使用 `AsyncPostgresSaver`
|
||||
- **backend.py**:FastAPI 应用,提供 REST API 和 WebSocket 接口,端口 8001
|
||||
- **frontend.py**:Streamlit 前端,通过 HTTP 调用后端 API,实现友好的用户界面
|
||||
- **docker-compose.yml**:服务编排(PostgreSQL + Backend + Frontend)
|
||||
- **Dockerfile.backend**:后端镜像构建
|
||||
- **Dockerfile.frontend**:前端镜像构建
|
||||
- **.gitea/workflows/deploy.yml**:CI/CD 自动化部署
|
||||
|
||||
### 数据流
|
||||
详见 [QUICKSTART.md](QUICKSTART.md) 的 Docker 部署章节。
|
||||
|
||||
```
|
||||
用户输入 → Streamlit 前端 → FastAPI 后端 → AIAgentService
|
||||
→ LangGraph StateGraph → LLM + Tools → PostgreSQL (记忆)
|
||||
→ 返回响应 → 前端展示
|
||||
---
|
||||
|
||||
## ⚙️ 环境配置
|
||||
|
||||
### 必需的环境变量
|
||||
|
||||
在 `.env` 文件中配置:
|
||||
|
||||
```env
|
||||
# 智谱 AI API Key(必需)
|
||||
ZHIPUAI_API_KEY=your_api_key_here
|
||||
|
||||
# vLLM 本地模型 Token(可选)
|
||||
VLLM_LOCAL_KEY=token-abc123
|
||||
```
|
||||
|
||||
## 注意事项
|
||||
### 数据库配置
|
||||
|
||||
1. **文件安全**:所有文件读取操作仅限于 `./user_docs` 目录,防止路径遍历攻击
|
||||
2. **端口冲突**:后端使用 8001 端口,避免与本地 vLLM 服务的 8000 端口冲突
|
||||
3. **API 密钥**:请妥善保管 `.env` 文件中的 API 密钥,不要提交到版本控制系统
|
||||
4. **数据库持久化**:PostgreSQL 数据卷挂载到 `~/docker_volumes/postgres_data`,确保数据安全
|
||||
默认使用 PostgreSQL,连接字符串:
|
||||
```
|
||||
postgresql://postgres:mysecretpassword@localhost:5432/langgraph_db
|
||||
```
|
||||
|
||||
## 故障排除
|
||||
如使用 Docker Compose,数据库会在内部网络中自动配置。
|
||||
|
||||
### 问题:无法连接 PostgreSQL
|
||||
---
|
||||
|
||||
**解决方案:**
|
||||
## 🐛 故障排查
|
||||
|
||||
### 常见问题
|
||||
|
||||
**Q: 无法连接 PostgreSQL?**
|
||||
```bash
|
||||
# 检查容器是否运行
|
||||
docker ps | grep postgres-langgraph
|
||||
# 检查容器状态
|
||||
docker ps | grep postgres
|
||||
|
||||
# 查看容器日志
|
||||
# 查看日志
|
||||
docker logs postgres-langgraph
|
||||
|
||||
# 重新启动容器
|
||||
docker restart postgres-langgraph
|
||||
```
|
||||
|
||||
### 问题:后端启动失败
|
||||
|
||||
**解决方案:**
|
||||
**Q: 后端启动失败?**
|
||||
- 确认端口 8001 未被占用
|
||||
- 检查 `.env` 文件中的 API 密钥是否正确配置
|
||||
- 确认所有依赖包已正确安装
|
||||
- 查看启动日志,确认至少有一个模型初始化成功
|
||||
- 检查 `.env` 中的 API Key 是否正确
|
||||
- 查看启动日志确认模型初始化成功
|
||||
|
||||
### 问题:模型切换后无响应
|
||||
|
||||
**解决方案:**
|
||||
- 检查所选模型的配置是否正确(如智谱 API Key)
|
||||
- 确认 vLLM 容器是否正在运行(如果使用本地模型)
|
||||
- 查看后端日志,确认模型是否初始化成功
|
||||
**Q: 模型切换后无响应?**
|
||||
- 检查所选模型的配置是否正确
|
||||
- 确认 vLLM 容器是否运行(如使用本地模型)
|
||||
- 尝试切换到另一个模型
|
||||
|
||||
### 问题:工具调用失败
|
||||
更多问题排查请查看 [QUICKSTART.md](QUICKSTART.md)
|
||||
|
||||
**解决方案:**
|
||||
- 确认文件位于 `./user_docs` 目录下
|
||||
- 检查文件格式是否正确
|
||||
- 查看后端日志获取详细错误信息
|
||||
---
|
||||
|
||||
## 许可证
|
||||
## 📝 许可证
|
||||
|
||||
本项目采用 MIT 许可证。详见 [LICENSE](LICENSE) 文件。
|
||||
|
||||
## 贡献
|
||||
## 🤝 贡献
|
||||
|
||||
欢迎提交 Issue 和 Pull Request!
|
||||
|
||||
8
app/__init__.py
Normal file
8
app/__init__.py
Normal file
@@ -0,0 +1,8 @@
|
||||
"""
|
||||
AI Agent 应用模块
|
||||
"""
|
||||
|
||||
from .agent import AIAgentService
|
||||
from .tools import AVAILABLE_TOOLS, TOOLS_BY_NAME
|
||||
|
||||
__all__ = ["AIAgentService", "AVAILABLE_TOOLS", "TOOLS_BY_NAME"]
|
||||
@@ -11,8 +11,8 @@ from langchain_openai import ChatOpenAI
|
||||
from pydantic import SecretStr
|
||||
|
||||
# 本地模块
|
||||
from graph_builder import GraphBuilder
|
||||
from tools import AVAILABLE_TOOLS, TOOLS_BY_NAME
|
||||
from app.graph_builder import GraphBuilder
|
||||
from app.tools import AVAILABLE_TOOLS, TOOLS_BY_NAME
|
||||
|
||||
load_dotenv()
|
||||
|
||||
@@ -44,7 +44,9 @@ class AIAgentService:
|
||||
def _create_local_llm(self):
|
||||
"""创建本地 vLLM 服务 LLM"""
|
||||
return ChatOpenAI(
|
||||
base_url="http://localhost:8000/v1",
|
||||
# 原来是 http://localhost:8000/v1
|
||||
# 改为 FRP 穿透后的公网地址
|
||||
base_url = "http://115.190.121.151:18000/v1",
|
||||
api_key=SecretStr(os.getenv("VLLM_LOCAL_KEY", "")),
|
||||
model="gemma-4-E2B-it",
|
||||
)
|
||||
@@ -11,7 +11,7 @@ from fastapi.middleware.cors import CORSMiddleware
|
||||
from pydantic import BaseModel
|
||||
from langgraph.checkpoint.postgres.aio import AsyncPostgresSaver
|
||||
|
||||
from agent import AIAgentService
|
||||
from app.agent import AIAgentService
|
||||
|
||||
# PostgreSQL 连接字符串
|
||||
DB_URI = "postgresql://postgres:mysecretpassword@localhost:5432/langgraph_db?sslmode=disable"
|
||||
16
data/user_docs/README.md
Normal file
16
data/user_docs/README.md
Normal file
@@ -0,0 +1,16 @@
|
||||
# 用户文档目录
|
||||
|
||||
将您的文档文件(.txt, .pdf, .xlsx 等)放在此目录中,AI Agent 可以读取和分析这些文件。
|
||||
|
||||
## 支持的文件格式
|
||||
|
||||
- 📄 **文本文件**: `.txt`, `.md`
|
||||
- 📑 **PDF 文档**: `.pdf`
|
||||
- 📊 **Excel 表格**: `.xlsx`, `.xls`
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. 所有文件必须是可读格式
|
||||
2. 文件大小建议不超过 50MB
|
||||
3. 敏感信息请勿放入此目录
|
||||
4. 文件内容会被用于 AI 分析和检索
|
||||
22
docker/Dockerfile.backend
Normal file
22
docker/Dockerfile.backend
Normal file
@@ -0,0 +1,22 @@
|
||||
FROM python:3.11-slim
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# 复制依赖文件并安装(利用 Docker 层缓存)
|
||||
COPY requirement.txt .
|
||||
RUN pip install --no-cache-dir -r requirement.txt
|
||||
|
||||
# 复制项目代码
|
||||
COPY app/ ./app/
|
||||
COPY frontend/ ./frontend/
|
||||
COPY data/ ./data/
|
||||
COPY scripts/ ./scripts/
|
||||
|
||||
# 设置 PYTHONPATH 确保模块能被找到
|
||||
ENV PYTHONPATH=/app
|
||||
|
||||
# 暴露端口(文档用途)
|
||||
EXPOSE 8001
|
||||
|
||||
# 启动命令
|
||||
CMD ["python", "app/backend.py"]
|
||||
15
docker/Dockerfile.frontend
Normal file
15
docker/Dockerfile.frontend
Normal file
@@ -0,0 +1,15 @@
|
||||
FROM python:3.11-slim
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY requirement.txt .
|
||||
RUN pip install --no-cache-dir -r requirement.txt
|
||||
|
||||
COPY frontend/ ./frontend/
|
||||
COPY app/ ./app/
|
||||
|
||||
ENV PYTHONPATH=/app
|
||||
|
||||
EXPOSE 8501
|
||||
|
||||
CMD ["streamlit", "run", "frontend/frontend.py", "--server.port", "8501", "--server.address", "0.0.0.0"]
|
||||
63
docker/docker-compose.yml
Normal file
63
docker/docker-compose.yml
Normal file
@@ -0,0 +1,63 @@
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:16
|
||||
container_name: ai-postgres
|
||||
environment:
|
||||
POSTGRES_PASSWORD: mysecretpassword # 请替换为强密码
|
||||
POSTGRES_DB: langgraph_db
|
||||
volumes:
|
||||
- pg_data:/var/lib/postgresql/data
|
||||
networks:
|
||||
- ai-network
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U postgres"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
restart: unless-stopped
|
||||
# 如需外部访问数据库,取消下面注释
|
||||
# ports:
|
||||
# - "5432:5432"
|
||||
|
||||
backend:
|
||||
build:
|
||||
context: .. # 构建上下文为项目根目录
|
||||
dockerfile: docker/Dockerfile.backend
|
||||
container_name: ai-backend
|
||||
environment:
|
||||
- ZHIPUAI_API_KEY=${ZHIPUAI_API_KEY}
|
||||
- VLLM_LOCAL_KEY=${VLLM_LOCAL_KEY}
|
||||
- DB_URI=postgresql://postgres:mysecretpassword@postgres:5432/langgraph_db?sslmode=disable
|
||||
volumes:
|
||||
- ../data/user_docs:/app/data/user_docs # 挂载文档目录
|
||||
- ../logs:/app/logs
|
||||
networks:
|
||||
- ai-network
|
||||
depends_on:
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
restart: unless-stopped
|
||||
|
||||
frontend:
|
||||
build:
|
||||
context: ..
|
||||
dockerfile: docker/Dockerfile.frontend
|
||||
container_name: ai-frontend
|
||||
environment:
|
||||
- API_URL=http://backend:8001/chat
|
||||
ports:
|
||||
- "8501:8501"
|
||||
networks:
|
||||
- ai-network
|
||||
depends_on:
|
||||
- backend
|
||||
restart: unless-stopped
|
||||
|
||||
networks:
|
||||
ai-network:
|
||||
driver: bridge
|
||||
|
||||
volumes:
|
||||
pg_data:
|
||||
8
start.sh → scripts/start.sh
Normal file → Executable file
8
start.sh → scripts/start.sh
Normal file → Executable file
@@ -84,7 +84,9 @@ check_postgres() {
|
||||
# 启动后端
|
||||
start_backend() {
|
||||
echo -e "\n${BLUE}🚀 启动后端服务 (端口 8001)...${NC}"
|
||||
python backend.py &
|
||||
cd /home/huang/Study/AIProject/Agent1
|
||||
export PYTHONPATH=$(pwd)
|
||||
python app/backend.py &
|
||||
BACKEND_PID=$!
|
||||
echo -e "${GREEN}✓ 后端服务已启动 (PID: $BACKEND_PID)${NC}"
|
||||
sleep 2
|
||||
@@ -93,7 +95,9 @@ start_backend() {
|
||||
# 启动前端
|
||||
start_frontend() {
|
||||
echo -e "\n${BLUE}🎨 启动前端界面...${NC}"
|
||||
streamlit run frontend.py &
|
||||
cd /home/huang/Study/AIProject/Agent1
|
||||
export PYTHONPATH=$(pwd)
|
||||
streamlit run frontend/frontend.py &
|
||||
FRONTEND_PID=$!
|
||||
echo -e "${GREEN}✓ 前端服务已启动 (PID: $FRONTEND_PID)${NC}"
|
||||
echo -e "${GREEN}✓ 请在浏览器中打开: http://localhost:8501${NC}"
|
||||
@@ -1,134 +0,0 @@
|
||||
"""
|
||||
多模型切换功能测试脚本
|
||||
用于验证后端是否正确支持多模型动态切换
|
||||
"""
|
||||
|
||||
import requests
|
||||
import json
|
||||
|
||||
API_URL = "http://localhost:8001/chat"
|
||||
|
||||
|
||||
def test_model_switching():
|
||||
"""测试模型切换功能"""
|
||||
|
||||
print("=" * 60)
|
||||
print("测试多模型切换功能")
|
||||
print("=" * 60)
|
||||
|
||||
# 测试消息
|
||||
test_message = "你好,请简单介绍一下自己"
|
||||
|
||||
# 测试不同的模型
|
||||
models_to_test = ["zhipu", "local"]
|
||||
|
||||
for model in models_to_test:
|
||||
print(f"\n📤 测试模型: {model}")
|
||||
print("-" * 60)
|
||||
|
||||
try:
|
||||
response = requests.post(
|
||||
API_URL,
|
||||
json={
|
||||
"message": test_message,
|
||||
"model": model
|
||||
},
|
||||
timeout=30
|
||||
)
|
||||
|
||||
if response.status_code == 200:
|
||||
data = response.json()
|
||||
print(f"✅ 成功!")
|
||||
print(f" 使用的模型: {data['model_used']}")
|
||||
print(f" 会话 ID: {data['thread_id'][:8]}...")
|
||||
print(f" 回复预览: {data['reply'][:100]}...")
|
||||
else:
|
||||
print(f"❌ 失败! 状态码: {response.status_code}")
|
||||
print(f" 错误信息: {response.text}")
|
||||
|
||||
except requests.exceptions.Timeout:
|
||||
print(f"⏰ 超时! 模型 '{model}' 响应时间过长")
|
||||
except requests.exceptions.ConnectionError:
|
||||
print(f"🔌 连接失败! 请确认后端服务正在运行 (python backend.py)")
|
||||
except Exception as e:
|
||||
print(f"💥 异常: {str(e)}")
|
||||
|
||||
print("\n" + "=" * 60)
|
||||
print("测试完成!")
|
||||
print("=" * 60)
|
||||
|
||||
|
||||
def test_conversation_memory():
|
||||
"""测试跨模型的会话记忆"""
|
||||
|
||||
print("\n" + "=" * 60)
|
||||
print("测试跨模型会话记忆")
|
||||
print("=" * 60)
|
||||
|
||||
import uuid
|
||||
thread_id = str(uuid.uuid4())
|
||||
|
||||
print(f"\n📝 使用固定会话 ID: {thread_id[:8]}...")
|
||||
|
||||
# 第一轮对话 - 使用 zhipu 模型
|
||||
print("\n📤 第1轮 - 使用 zhipu 模型")
|
||||
try:
|
||||
response1 = requests.post(
|
||||
API_URL,
|
||||
json={
|
||||
"message": "我叫小明,记住我的名字",
|
||||
"thread_id": thread_id,
|
||||
"model": "zhipu"
|
||||
},
|
||||
timeout=30
|
||||
)
|
||||
if response1.status_code == 200:
|
||||
data1 = response1.json()
|
||||
print(f" ✅ 回复: {data1['reply'][:100]}...")
|
||||
print(f" 🤖 使用模型: {data1['model_used']}")
|
||||
except Exception as e:
|
||||
print(f" ❌ 失败: {e}")
|
||||
return
|
||||
|
||||
# 第二轮对话 - 切换到 local 模型,测试是否记得名字
|
||||
print("\n📤 第2轮 - 切换到 local 模型")
|
||||
try:
|
||||
response2 = requests.post(
|
||||
API_URL,
|
||||
json={
|
||||
"message": "我叫什么名字?",
|
||||
"thread_id": thread_id,
|
||||
"model": "local"
|
||||
},
|
||||
timeout=30
|
||||
)
|
||||
if response2.status_code == 200:
|
||||
data2 = response2.json()
|
||||
print(f" ✅ 回复: {data2['reply'][:100]}...")
|
||||
print(f" 🤖 使用模型: {data2['model_used']}")
|
||||
|
||||
# 检查是否记得名字
|
||||
if "小明" in data2['reply']:
|
||||
print(" 🎉 成功!跨模型记忆功能正常")
|
||||
else:
|
||||
print(" ⚠️ 注意:模型可能没有正确回忆上下文")
|
||||
except Exception as e:
|
||||
print(f" ❌ 失败: {e}")
|
||||
|
||||
print("\n" + "=" * 60)
|
||||
print("会话记忆测试完成!")
|
||||
print("=" * 60)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("\n⚠️ 请确保后端服务正在运行 (python backend.py)\n")
|
||||
|
||||
# 运行基本测试
|
||||
test_model_switching()
|
||||
|
||||
# 询问是否运行记忆测试
|
||||
choice = input("\n是否运行会话记忆测试?(y/n): ").strip().lower()
|
||||
if choice == 'y':
|
||||
test_conversation_memory()
|
||||
|
||||
print("\n✨ 所有测试完成!")
|
||||
Reference in New Issue
Block a user