Files
ailine/scripts/start.sh
root 8dd94c6c19
All checks were successful
构建并部署 AI Agent 服务 / deploy (push) Successful in 27s
添加长期记忆
2026-04-14 17:34:12 +08:00

386 lines
12 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/bash
# =============================================================================
# AI Agent 启动与管理脚本
# 用法: ./start.sh [check|backend|frontend|both|docker-up|docker-down]
# =============================================================================
set -e
# 颜色定义
GREEN='\033[0;32m'
BLUE='\033[0;34m'
RED='\033[0;31m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# 项目根目录
PROJECT_DIR="/home/huang/Study/AIProject/Agent1"
echo -e "${BLUE}========================================${NC}"
echo -e "${BLUE} AI Agent - 个人生活助手${NC}"
echo -e "${BLUE}========================================${NC}"
echo ""
# =============================================================================
# 配置检查函数
# =============================================================================
check_config() {
echo -e "${BLUE}📋 开始环境配置检查...${NC}"
echo ""
PASS=0
FAIL=0
WARN=0
# 辅助函数
check_pass() {
echo -e "${GREEN}${NC} $1"
((PASS++))
}
check_fail() {
echo -e "${RED}${NC} $1"
((FAIL++))
}
check_warn() {
echo -e "${YELLOW}${NC} $1"
((WARN++))
}
# 1. 检查 .env 文件
echo "🔍 检查配置文件..."
if [ -f "$PROJECT_DIR/.env" ]; then
check_pass ".env 文件存在"
# 检查文件格式
if grep -q "^EOF" .env 2>/dev/null; then
check_fail ".env 文件格式错误:发现多余的 EOF 标记"
else
check_pass ".env 文件格式正确"
fi
else
check_fail ".env 文件不存在"
echo " 提示: 请创建 .env 文件并配置环境变量"
return 1
fi
# 2. 检查必需的环境变量
echo ""
echo "🔑 检查环境变量..."
# 检查 ZHIPUAI_API_KEY
if grep -q "^ZHIPUAI_API_KEY=" "$PROJECT_DIR/.env" 2>/dev/null; then
API_KEY=$(grep "^ZHIPUAI_API_KEY=" "$PROJECT_DIR/.env" | head -1 | cut -d'=' -f2- | tr -d '[:space:]')
if [ ${#API_KEY} -gt 10 ]; then
check_pass "ZHIPUAI_API_KEY 已配置(长度: ${#API_KEY}"
else
check_fail "ZHIPUAI_API_KEY 配置可能无效(过短)"
fi
else
check_fail "ZHIPUAI_API_KEY 未配置或格式错误"
fi
# 检查 VLLM_LOCAL_KEY
if grep -q "^VLLM_LOCAL_KEY=" "$PROJECT_DIR/.env" 2>/dev/null; then
check_pass "VLLM_LOCAL_KEY 已配置"
else
check_warn "VLLM_LOCAL_KEY 未配置(如不使用本地模型可忽略)"
fi
# 检查 DB_URI
if grep -q "^DB_URI=" "$PROJECT_DIR/.env" 2>/dev/null; then
check_pass "DB_URI 已配置"
else
check_warn "DB_URI 未配置(将使用默认值)"
fi
# 3. 检查 Docker 环境
echo ""
echo "🐳 检查 Docker 环境..."
if command -v docker &> /dev/null; then
check_pass "Docker 已安装"
if docker info &> /dev/null; then
check_pass "Docker 守护进程正在运行"
else
check_fail "Docker 守护进程未运行"
echo " 提示: sudo systemctl start docker"
fi
else
check_fail "Docker 未安装"
fi
if command -v docker compose version &> /dev/null || command -v docker-compose &> /dev/null; then
check_pass "Docker Compose 已安装"
else
check_fail "Docker Compose 未安装"
fi
# 4. 检查端口占用
echo ""
echo "🔌 检查端口占用..."
for port in 8001 8501; do
if lsof -i :$port &> /dev/null; then
check_warn "端口 $port 已被占用"
else
check_pass "端口 $port 可用"
fi
done
# 总结
echo ""
echo "=========================================="
echo " 检查结果汇总"
echo "=========================================="
echo -e "${GREEN}通过: $PASS${NC}"
echo -e "${RED}失败: $FAIL${NC}"
echo -e "${YELLOW}警告: $WARN${NC}"
echo ""
if [ $FAIL -eq 0 ]; then
echo -e "${GREEN}✅ 配置检查通过!${NC}"
return 0
else
echo -e "${RED}❌ 发现 $FAIL 个错误,请修复后重试${NC}"
return 1
fi
}
# =============================================================================
# Docker 容器检查函数
# =============================================================================
check_vllm() {
echo -e "${BLUE}🔍 检查 vLLM 容器...${NC}"
if ! docker ps --format '{{.Names}}' | grep -q "^gemma4-server$"; then
echo -e "${YELLOW}⚠️ vLLM 容器未运行${NC}"
return 1
else
echo -e "${GREEN}✓ vLLM 容器正在运行 (gemma4-server)${NC}"
return 0
fi
}
check_postgres() {
echo -e "${BLUE}🔍 检查 PostgreSQL 容器...${NC}"
if ! docker ps --format '{{.Names}}' | grep -q "^postgres-langgraph$"; then
echo -e "${YELLOW}⚠️ PostgreSQL 容器未运行${NC}"
return 1
else
echo -e "${GREEN}✓ PostgreSQL 容器正在运行 (postgres-langgraph)${NC}"
return 0
fi
}
# =============================================================================
# 启动 Docker 依赖服务
# =============================================================================
start_vllm() {
echo -e "${BLUE}🚀 启动 vLLM 容器...${NC}"
# 检查模型文件
if [ ! -d "/home/huang/Study/AIModel/gemma-4-E2B-it" ]; then
echo -e "${RED}✗ 错误:模型目录不存在: /home/huang/Study/AIModel/gemma-4-E2B-it${NC}"
exit 1
fi
docker run -d \
--name gemma4-server \
--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
echo -e "${GREEN}✓ vLLM 容器已启动${NC}"
echo -e "${YELLOW}⏳ 等待模型加载(可能需要几分钟)...${NC}"
sleep 10
}
start_postgres() {
echo -e "${BLUE}🚀 启动 PostgreSQL 容器...${NC}"
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
echo -e "${GREEN}✓ PostgreSQL 容器已启动${NC}"
sleep 3
}
# =============================================================================
# 启动 Python 服务
# =============================================================================
start_backend() {
echo -e "\n${BLUE}🚀 启动后端服务 (端口 8001)...${NC}"
cd "$PROJECT_DIR"
# 加载 .env 文件中的环境变量
set -a
source .env 2>/dev/null || true
set +a
export PYTHONPATH="$PROJECT_DIR"
python app/backend.py &
BACKEND_PID=$!
echo -e "${GREEN}✓ 后端服务已启动 (PID: $BACKEND_PID)${NC}"
sleep 2
}
start_frontend() {
echo -e "\n${BLUE}🎨 启动前端界面 (端口 8501)...${NC}"
cd "$PROJECT_DIR"
# 加载 .env 文件中的环境变量
set -a
source .env 2>/dev/null || true
set +a
export PYTHONPATH="$PROJECT_DIR"
streamlit run frontend/frontend.py &
FRONTEND_PID=$!
echo -e "${GREEN}✓ 前端服务已启动 (PID: $FRONTEND_PID)${NC}"
echo -e "${GREEN}✓ 访问地址:${NC}"
echo -e " 本地开发: http://localhost:8501"
echo -e " Nginx代理: http://your-domain.com"
}
# =============================================================================
# Docker Compose 管理
# =============================================================================
docker_up() {
echo -e "${BLUE}🐳 使用 Docker Compose 启动所有服务...${NC}"
cd "$PROJECT_DIR"
# 检查 .env 文件
if [ ! -f ".env" ]; then
echo -e "${RED}✗ 错误:.env 文件不存在${NC}"
echo " 请先复制配置文件:"
echo " cp .env.docker .env # 服务器部署"
echo " 或"
echo " cp .env.local .env # 本地开发"
exit 1
fi
docker compose -f docker/docker-compose.yml up -d --build
echo -e "\n${GREEN}✓ Docker Compose 服务已启动${NC}"
echo -e "${BLUE}📊 查看服务状态:${NC} docker compose -f docker/docker-compose.yml ps"
echo -e "${BLUE}📝 查看日志:${NC} docker compose -f docker/docker-compose.yml logs -f"
echo -e "${BLUE}🌐 访问应用:${NC} http://localhost:8501"
}
docker_down() {
echo -e "${BLUE}🛑 停止 Docker Compose 服务...${NC}"
cd "$PROJECT_DIR"
docker compose -f docker/docker-compose.yml down
echo -e "${GREEN}✓ 服务已停止${NC}"
}
# =============================================================================
# 清理函数
# =============================================================================
cleanup() {
echo -e "\n${RED}🛑 正在停止 Python 服务...${NC}"
if [ ! -z "$BACKEND_PID" ]; then
kill $BACKEND_PID 2>/dev/null || true
echo -e "${GREEN}✓ 后端服务已停止${NC}"
fi
if [ ! -z "$FRONTEND_PID" ]; then
kill $FRONTEND_PID 2>/dev/null || true
echo -e "${GREEN}✓ 前端服务已停止${NC}"
fi
echo -e "${YELLOW}💡 提示Docker 容器需要手动停止${NC}"
echo -e " 停止 vLLM: docker stop gemma4-server"
echo -e " 停止 PostgreSQL: docker stop postgres-langgraph"
echo -e " 或使用: $0 docker-down"
exit 0
}
# 捕获 Ctrl+C
trap cleanup SIGINT SIGTERM
# =============================================================================
# 主逻辑
# =============================================================================
case "${1:-help}" in
check)
check_config
;;
backend)
check_config || exit 1
check_vllm || start_vllm
check_postgres || start_postgres
start_backend
echo -e "\n${GREEN}后端服务正在运行,按 Ctrl+C 停止${NC}"
wait $BACKEND_PID
;;
frontend)
check_config || exit 1
start_frontend
echo -e "\n${GREEN}前端服务正在运行,按 Ctrl+C 停止${NC}"
wait $FRONTEND_PID
;;
both)
check_config || exit 1
check_vllm || start_vllm
check_postgres || start_postgres
start_backend
start_frontend
echo -e "\n${GREEN}所有服务正在运行,按 Ctrl+C 停止 Python 服务${NC}"
echo -e "${YELLOW}注意Docker 容器会在后台继续运行${NC}"
wait
;;
docker-up)
check_config || exit 1
docker_up
;;
docker-down)
docker_down
;;
help|*)
echo -e "${BLUE}用法:${NC} $0 [command]"
echo ""
echo -e "${BLUE}命令:${NC}"
echo " check 检查环境配置"
echo " backend 仅启动后端服务"
echo " frontend 仅启动前端服务"
echo " both 启动前后端服务(默认)"
echo " docker-up 使用 Docker Compose 启动所有服务"
echo " docker-down 停止 Docker Compose 服务"
echo " help 显示此帮助信息"
echo ""
echo -e "${BLUE}示例:${NC}"
echo " $0 check # 检查配置"
echo " $0 both # 启动本地开发环境"
echo " $0 docker-up # 启动 Docker 部署环境"
;;
esac